langgenius/dify · error · PipelineNotFoundError
pipeline_not_found
pipeline_not_found
Error message
Pipeline not found.
What it means
Raised as PipelineNotFoundError (error_code pipeline_not_found, HTTP 404) by load_rag_pipeline in wraps.py, which is invoked by the @get_rag_pipeline decorator used on nearly every /rag/pipelines/<pipeline_id>/... route. When RagPipelineService.get_pipeline_by_id cannot find a pipeline with the given id for the current tenant, the decorator raises this before the view runs.
Source
Thrown at api/controllers/console/datasets/wraps.py:17
from collections.abc import Callable
from functools import wraps
from sqlalchemy.orm import Session
from controllers.console.datasets.error import PipelineNotFoundError
from extensions.ext_database import db
from libs.login import current_account_with_tenant
from models.dataset import Pipeline
from services.rag_pipeline.rag_pipeline import RagPipelineService
def load_rag_pipeline(session: Session, pipeline_id: str) -> Pipeline:
_, current_tenant_id = current_account_with_tenant()
pipeline = RagPipelineService.get_pipeline_by_id(pipeline_id, current_tenant_id, session=session)
if not pipeline:
raise PipelineNotFoundError()
return pipeline
def get_rag_pipeline[**P, R](view_func: Callable[P, R]) -> Callable[P, R]:
@wraps(view_func)
def decorated_view(*args: P.args, **kwargs: P.kwargs) -> R:
if not kwargs.get("pipeline_id"):
raise ValueError("missing pipeline_id in path parameters")
pipeline_id = kwargs.get("pipeline_id")
pipeline_id = str(pipeline_id)
del kwargs["pipeline_id"]
kwargs["pipeline"] = load_rag_pipeline(db.session(), pipeline_id)
return view_func(*args, **kwargs)
return decorated_viewView on GitHub (pinned to ef8544b173)
Solutions
- Re-fetch the pipelines list for the current tenant and use a valid pipeline_id.
- Confirm the authenticated user belongs to the tenant that owns the pipeline.
- On the client, handle pipeline_not_found by refreshing the pipeline list.
- Do not persist pipeline_ids across environment switches (dev/staging/prod).
Example fix
// before GET /rag/pipelines/<wrong-id>/workflows // -> 404 pipeline_not_found // after pipelines = await GET /rag/pipelines GET /rag/pipelines/<pipelines[0].id>/workflows
Defensive patterns
Strategy: validation
Validate before calling
async function withPipeline(pipelineId, fn) {
const list = await fetch('/rag/pipelines').then(r => r.json());
if (!(list.items ?? []).some(p => p.id === pipelineId)) throw new Error('pipeline_not_found');
return fn(pipelineId);
} Type guard
function isKnownPipelineId(list, id) { return Array.isArray(list?.items) && list.items.some(p => p.id === id); } Try / catch
try { return await withPipeline(id, pid => fetchAnyPipelineRoute(pid)); } catch (e) { if (e.code === 'pipeline_not_found' || e.status === 404) refreshPipelines(); else throw e; } Prevention
- Fetch the pipeline list for the current tenant before deep-linking.
- Handle pipeline_not_found by refreshing.
- Do not reuse pipeline_ids across tenants/environments.
When it happens
Trigger: Any RAG-pipeline route called with a pipeline_id that does not exist, was deleted, or belongs to a different tenant. Also raised if pipeline_id is omitted from kwargs (though that path raises a different ValueError first). Every controller method decorated with @get_rag_pipeline funnels through this check.
Common situations: Deep link to a deleted pipeline; pipeline_id copied across tenants/environments; pipeline still being created; permission/tenant scope mismatch on the session.
Related errors
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/33d4e9b66370fdf9.
Report an issue: GitHub.