{"record":{"id":"2099f05f61610a8f","repo":"langflow-ai/langflow","slug":"flow-not-found-2099f0","errorCode":null,"errorMessage":"Flow not found.","messagePattern":"Flow not found\\.","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"src/backend/base/langflow/agentic/utils/assistant_runner.py","lineNumber":44,"sourceCode":"from langflow.services.database.models.flow.guards import ensure_flow_unlocked, lock_flow_for_update\nfrom langflow.services.database.models.flow.model import Flow, FlowCreate\nfrom langflow.services.deps import get_storage_service\n\nif TYPE_CHECKING:\n    from sqlmodel.ext.asyncio.session import AsyncSession\n\nDEFAULT_FLOW_NAME = \"Assistant Flow\"\n\n\nasync def _ensure_flow(session: AsyncSession, user_id: UUID, flow_id: str | None) -> tuple[Flow, bool]:\n    if flow_id:\n        try:\n            flow_uuid = UUID(flow_id)\n        except ValueError as exc:\n            raise HTTPException(status_code=422, detail=\"Invalid flow_id: not a valid UUID.\") from exc\n        flow = await session.get(Flow, flow_uuid)\n        if flow is None or (flow.user_id is not None and str(flow.user_id) != str(user_id)):\n            raise HTTPException(status_code=404, detail=\"Flow not found.\")\n        return flow, False\n\n    folder = await get_or_create_default_folder(session, user_id)\n    new_flow = FlowCreate(\n        name=DEFAULT_FLOW_NAME,\n        description=\"Created by the Langflow Assistant via MCP\",\n        data={\"nodes\": [], \"edges\": []},\n        folder_id=folder.id,\n        user_id=user_id,\n    )\n    storage_service = get_storage_service()\n    created = await _new_flow(session=session, flow=new_flow, user_id=user_id, storage_service=storage_service)\n    await session.commit()\n    # _new_flow returns a FlowRead; re-fetch the ORM row so later edits persist.\n    db_flow = await session.get(Flow, created.id)\n    if db_flow is None:\n        raise HTTPException(status_code=500, detail=\"Flow creation failed.\")\n    return db_flow, True","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/agentic/utils/assistant_runner.py#L26-L62","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["List your flows (GET /api/v1/flows/) and confirm the id still exists and belongs to the calling user.","Omit flow_id entirely — the assistant creates a fresh 'Assistant Flow' in your default folder.","If the flow should be shared across users, use the deployment/share mechanisms rather than passing the owner's id."],"exampleFix":"# before\nawait run_assistant(flow_id=\"<id copied from another user>\", ...)\n\n# after\n# omit flow_id and let the assistant create/resolve its own flow\nawait run_assistant(...)","handlingStrategy":"validation","validationCode":"async def flow_exists_and_owned(client, flow_id: str, user_id: str) -> bool:\n    res = await client.get(f\"/api/v1/flows/{flow_id}\")\n    if res.status_code != 200:\n        return False\n    return res.json().get(\"user_id\") in (None, user_id)","typeGuard":null,"tryCatchPattern":"try:\n    result = await run_assistant(flow_id=flow_id)\nexcept HTTPError as e:\n    if e.response.status_code == 404:\n        result = await run_assistant()  # let it create a fresh Assistant Flow\n    else:\n        raise","preventionTips":["Handle 404 by re-resolving or omitting flow_id rather than retrying the same id.","Do not cache flow ids indefinitely; refresh them per session.","Remember 404 also masks 'exists but owned by someone else' — that is intentional."],"tags":["http-404","ownership","assistant","flows"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}