langflow-ai/langflow · error · HTTPException

Flow not found.

Error message

Flow not found.

What it means

Raised by _validate_flow_access when the supplied flow_id parses as a UUID but no Flow row with that id exists, or the row belongs to a different user. Not-found and cross-user access deliberately share the same 404 so that flow existence is not leaked by id probing. This mirrors the per-user 404 behavior of the /run and webhook endpoints.

Source

Thrown at src/backend/base/langflow/agentic/api/router.py:160

    A missing flow_id is allowed (the assistant runs with no canvas context).
    A supplied id must reference a flow the caller can access, mirroring the
    per-user 404 of the /run and webhook endpoints; not-found and cross-user
    both surface 404 so a flow's existence is not leaked by id.
    """
    if not flow_id:
        return

    from langflow.services.database.models.flow import Flow

    try:
        flow_uuid = UUID(flow_id)
    except ValueError as exc:
        raise HTTPException(status_code=422, detail="Invalid flow_id: not a valid UUID.") from exc

    flow = await session.get(Flow, flow_uuid)
    if flow is None or (flow.user_id is not None and str(flow.user_id) != str(user_id)):
        raise HTTPException(status_code=404, detail="Flow not found.")


@router.post("/execute/{flow_name}", dependencies=[Depends(require_agentic_experience)])
async def execute_named_flow(
    flow_name: str,
    request: AssistantRequest,
    current_user: CurrentActiveUser,
    session: DbSession,
) -> dict:
    """Execute a named flow from the flows directory.

    Named assistant flows embed an Agent that needs provider/model/api-key
    context. Resolving it here (instead of running the raw file) turns a
    silent 500 into a successful run, or a clear 4xx when no provider is set.
    """
    ctx = await _resolve_assistant_context(request, current_user.id, session)

    global_vars = dict(ctx.global_vars)

View on GitHub (pinned to 976ec789d2)

Solutions

  1. Re-fetch the caller's flows (GET /api/v1/flows) and use an id from that list.
  2. If the flow was deleted, recreate it or clear the stored flow_id so the assistant runs without canvas context.
  3. For genuine cross-user sharing, enable the RBAC authorization layer with a plugin that supports cross-user fetch instead of relying on the OSS pass-through.
  4. Confirm you are authenticated as the same user that owns the flow (token from the right account).
Defensive patterns

Strategy: validation

Validate before calling

// Only send flow_ids the caller can actually see
const flows = await fetch('/api/v1/flows').then(r => r.json());
const owned = new Set(flows.map(f => f.id));
if (flowId && !owned.has(flowId)) flowId = undefined;

Try / catch

Treat 404 as terminal for that flow_id: clear cached id, refresh the flow list, and either retry with a fresh id or proceed without flow_id. Do not blind-retry the same id.

Prevention

When it happens

Trigger: POST /api/v1/agentic/assist* with a flow_id that is a well-formed UUID but deleted, never existed, or owned by another user; also flows whose user_id differs from the authenticated CurrentActiveUser.

Common situations: Flow deleted after the client captured its id; sharing a flow id between accounts and expecting cross-user access without the authorization plugin; stale local storage in the frontend holding an old flow id; database reset wiping flows while the session kept the id.

Related errors


AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14). Data as JSON: /api/errors/bd922cd0b8f9123e. Report an issue: GitHub.