langflow-ai/langflow · error · HTTPException

Flow not found.

Error message

Flow not found.

What it means

Raised by _ensure_flow when the UUID is well-formed but either no Flow row with that id exists, or the row exists and its user_id is set and differs from the caller's user_id. Owner-scoping is enforced here (a NULL flow.user_id is treated as accessible). Deliberately returns 404 rather than 403 so foreign flow UUIDs are not confirmed to exist.

Source

Thrown at src/backend/base/langflow/agentic/utils/assistant_runner.py:44

from langflow.services.database.models.flow.guards import ensure_flow_unlocked, lock_flow_for_update
from langflow.services.database.models.flow.model import Flow, FlowCreate
from langflow.services.deps import get_storage_service

if TYPE_CHECKING:
    from sqlmodel.ext.asyncio.session import AsyncSession

DEFAULT_FLOW_NAME = "Assistant Flow"


async def _ensure_flow(session: AsyncSession, user_id: UUID, flow_id: str | None) -> tuple[Flow, bool]:
    if flow_id:
        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.")
        return flow, False

    folder = await get_or_create_default_folder(session, user_id)
    new_flow = FlowCreate(
        name=DEFAULT_FLOW_NAME,
        description="Created by the Langflow Assistant via MCP",
        data={"nodes": [], "edges": []},
        folder_id=folder.id,
        user_id=user_id,
    )
    storage_service = get_storage_service()
    created = await _new_flow(session=session, flow=new_flow, user_id=user_id, storage_service=storage_service)
    await session.commit()
    # _new_flow returns a FlowRead; re-fetch the ORM row so later edits persist.
    db_flow = await session.get(Flow, created.id)
    if db_flow is None:
        raise HTTPException(status_code=500, detail="Flow creation failed.")
    return db_flow, True

View on GitHub (pinned to 976ec789d2)

Solutions

  1. List your flows (GET /api/v1/flows/) and confirm the id still exists and belongs to the calling user.
  2. Omit flow_id entirely — the assistant creates a fresh 'Assistant Flow' in your default folder.
  3. If the flow should be shared across users, use the deployment/share mechanisms rather than passing the owner's id.

Example fix

# before
await run_assistant(flow_id="<id copied from another user>", ...)

# after
# omit flow_id and let the assistant create/resolve its own flow
await run_assistant(...)
Defensive patterns

Strategy: validation

Validate before calling

async def flow_exists_and_owned(client, flow_id: str, user_id: str) -> bool:
    res = await client.get(f"/api/v1/flows/{flow_id}")
    if res.status_code != 200:
        return False
    return res.json().get("user_id") in (None, user_id)

Try / catch

try:
    result = await run_assistant(flow_id=flow_id)
except HTTPError as e:
    if e.response.status_code == 404:
        result = await run_assistant()  # let it create a fresh Assistant Flow
    else:
        raise

Prevention

When it happens

Trigger: Passing a flow_id from another user's workspace; a flow deleted after the id was copied; a typo'd-but-valid UUID; using an id from a different environment (dev id in prod).

Common situations: Stale ids cached by an integration after the user recreated the flow; multi-user deployments where an assistant client reused a shared hardcoded flow id; database resets wiping flow rows.

Related errors


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