Skip to content

[Bug] TypeError: 'NoneType' object is not iterable in pipelines/main.py prevents service startup #560

@ttbj2023

Description

@ttbj2023

Description:

Hello OpenWebUI team,

I'm reporting a critical bug in the ghcr.io/open-webui/pipelines:main Docker image that prevents the pipelines service from fully initializing and registering any pipelines. This results in the OpenWebUI frontend consistently reporting "No Pipeline Detected".

Problem:

The pipelines service fails to start its core application due to a TypeError: 'NoneType' object is not iterable occurring in /app/main.py during the get_all_pipelines() function execution. This error happens specifically when processing a "manifold" type pipeline, even if the pipeline definition itself is correct.

Environment Configuration:

  • Operating System: Windows 10
  • Project Directory: C:\project\garp_pro (Host machine)
  • Docker Environment: Docker Desktop, repeatedly cleared/reset.
  • pipelines Service Image: ghcr.io/open-webui/pipelines:main (latest pulled image)
  • garp_pipeline.py Location: C:\project\garp_pro\pipelines\garp_pipeline.py
  • docker-compose.yml volume mount for pipelines: ./pipelines:/app/pipelines (verified correct, garp_pipeline.py is visible inside the container)

Pre‑conditions (My garp_pipeline.py setup):

My garp_pipeline.py is configured as a manifold type pipeline. Crucially, it correctly initializes self.pipelines to an empty list [], which should prevent issues from my side. Example snippet from my garp_pipeline.py:

class Pipeline:
    def __init__(self):
        self.id = "garp"
        self.name = "GARP Pipeline"
        self.type = "manifold"
        self.valves = ManifoldValves()
        self.pipelines = []  # <--- This is explicitly set to an empty list
        # ... other pipeline logic ...

Steps to Reproduce:

  1. Set up a docker-compose.yml file to run the openwebui, pipelines, and optionally garp services.
  2. Ensure the pipelines service uses image: ghcr.io/open-webui/pipelines:main and has a volume mount like ./pipelines:/app/pipelines where your custom pipelines reside.
  3. Place a valid manifold type pipeline file (e.g., garp_pipeline.py as described above) in the mounted ./pipelines directory.
  4. Run docker compose up -d.
  5. Observe the logs of the pipelines service (docker logs <pipelines_container_id>).

Expected Behavior:

The pipelines service should start without errors, load garp_pipeline.py, and OpenWebUI should detect the "garp" pipeline.

Observed Behavior:

  1. The pipelines service container starts, and its logs show Loaded module: garp_pipeline.
  2. Shortly after loading the module, the service encounters a TypeError: 'NoneType' object is not iterable at /app/main.py, line 62.
  3. The pipelines service application crashes/fails to fully initialize.
  4. OpenWebUI reports "No Pipeline Detected".

Detailed Code Analysis (Root Cause):

After reviewing the main.py source code, I've pinpointed the exact location and reason for the TypeError.

The issue occurs within the get_all_pipelines() function, specifically when processing a manifold type pipeline.

The relevant code block is:

# /app/main.py (lines 56-62 in the provided source)

def get_all_pipelines():
    pipelines = {}
    for pipeline_id in PIPELINE_MODULES.keys():
        pipeline = PIPELINE_MODULES[pipeline_id]

        if hasattr(pipeline, "type"):
            if pipeline.type == "manifold":
                manifold_pipelines = []

                # Check if pipelines is a function or a list
                if callable(pipeline.pipelines):
                    manifold_pipelines = pipeline.pipelines()
                else:
                    manifold_pipelines = pipeline.pipelines  # <--- Line 61: 'pipeline.pipelines' might be None here

                for p in manifold_pipelines:  # <--- Line 62: TypeError if 'manifold_pipelines' is None
                    manifold_pipeline_id = f'{pipeline_id}.{p["id"]}'
                    # ... rest of the loop ...

Reasoning:

  1. At line 61, manifold_pipelines = pipeline.pipelines directly assigns the value of pipeline.pipelines to manifold_pipelines.
  2. The code lacks a check to ensure pipeline.pipelines is not None before attempting to iterate over manifold_pipelines at line 62.
  3. If, for any reason (e.g., a custom pipeline has self.pipelines = None or the callable branch returns None), pipeline.pipelines evaluates to None, then manifold_pipelines becomes None.
  4. Consequently, the for p in manifold_pipelines: loop attempts to iterate over None, leading to the TypeError.

While my garp_pipeline.py explicitly sets self.pipelines = [], the main.py code is not robust enough to handle scenarios where pipeline.pipelines might be None (either due to a different custom pipeline or an unexpected internal state).

Suggested Fix (Code Patch):

To resolve this, a simple check can be added before the for loop to ensure manifold_pipelines is always an iterable (e.g., an empty list) if it happens to be None.

# /app/main.py (Proposed fix in get_all_pipelines())

def get_all_pipelines():
    # ... (existing code up to line 61) ...

                # Check if pipelines is a function or a list
                if callable(pipeline.pipelines):
                    manifold_pipelines = pipeline.pipelines()
                else:
                    manifold_pipelines = pipeline.pipelines

                # --- START OF PROPOSED FIX ---
                # Ensure manifold_pipelines is an iterable, even if initially None
                if manifold_pipelines is None:
                    manifold_pipelines = []
                # --- END OF PROPOSED FIX ---

                for p in manifold_pipelines:
                    manifold_pipeline_id = f'{pipeline_id}.{p["id"]}'
                    # ... rest of the code ...

Applying this patch locally (by building a custom Docker image) immediately resolves the TypeError and allows the pipelines service to start correctly, with OpenWebUI then detecting the pipelines.

Thank you for your attention to this issue. Let me know if you need any further information.


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions