-
-
Notifications
You must be signed in to change notification settings - Fork 642
Description
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.
pipelinesService Image:ghcr.io/open-webui/pipelines:main(latest pulled image)garp_pipeline.pyLocation:C:\project\garp_pro\pipelines\garp_pipeline.pydocker-compose.ymlvolume mount for pipelines:./pipelines:/app/pipelines(verified correct,garp_pipeline.pyis 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:
- Set up a
docker-compose.ymlfile to run theopenwebui,pipelines, and optionallygarpservices. - Ensure the
pipelinesservice usesimage: ghcr.io/open-webui/pipelines:mainand has a volume mount like./pipelines:/app/pipelineswhere your custom pipelines reside. - Place a valid
manifoldtype pipeline file (e.g.,garp_pipeline.pyas described above) in the mounted./pipelinesdirectory. - Run
docker compose up -d. - Observe the logs of the
pipelinesservice (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:
- The
pipelinesservice container starts, and its logs showLoaded module: garp_pipeline. - Shortly after loading the module, the service encounters a
TypeError: 'NoneType' object is not iterableat/app/main.py, line 62. - The
pipelinesservice application crashes/fails to fully initialize. - 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:
- At line 61,
manifold_pipelines = pipeline.pipelinesdirectly assigns the value ofpipeline.pipelinestomanifold_pipelines. - The code lacks a check to ensure
pipeline.pipelinesis notNonebefore attempting to iterate overmanifold_pipelinesat line 62. - If, for any reason (e.g., a custom pipeline has
self.pipelines = Noneor thecallablebranch returnsNone),pipeline.pipelinesevaluates toNone, thenmanifold_pipelinesbecomesNone. - Consequently, the
for p in manifold_pipelines:loop attempts to iterate overNone, leading to theTypeError.
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.