{"record":{"id":"839f1f8fc100d5a5","repo":"bytedance/deer-flow","slug":"thread-metadata-store-not-available","errorCode":null,"errorMessage":"Thread metadata store not available","messagePattern":"Thread metadata store not available","errorType":"http","errorClass":"HTTPException","httpStatus":503,"severity":"error","filePath":"backend/app/gateway/deps.py","lineNumber":640,"sourceCode":"\nget_stream_bridge: Callable[[Request], StreamBridge] = _require(\"stream_bridge\", \"Stream bridge\")\nget_run_manager: Callable[[Request], RunManager] = _require(\"run_manager\", \"Run manager\")\nget_checkpointer: Callable[[Request], Checkpointer] = _require(\"checkpointer\", \"Checkpointer\")\nget_run_event_store: Callable[[Request], RunEventStore] = _require(\"run_event_store\", \"Run event store\")\nget_feedback_repo: Callable[[Request], FeedbackRepository] = _require(\"feedback_repo\", \"Feedback\")\nget_run_store: Callable[[Request], RunStore] = _require(\"run_store\", \"Run store\")\n\n\ndef get_store(request: Request):\n    \"\"\"Return the global store (may be ``None`` if not configured).\"\"\"\n    return getattr(request.app.state, \"store\", None)\n\n\ndef get_thread_store(request: Request) -> ThreadMetaStore:\n    \"\"\"Return the thread metadata store (SQL or memory-backed).\"\"\"\n    val = getattr(request.app.state, \"thread_store\", None)\n    if val is None:\n        raise HTTPException(status_code=503, detail=\"Thread metadata store not available\")\n    return val\n\n\ndef get_scheduled_task_repo(request: Request):\n    val = getattr(request.app.state, \"scheduled_task_repo\", None)\n    if val is None:\n        raise HTTPException(status_code=503, detail=\"Scheduled task repo not available\")\n    return val\n\n\ndef get_scheduled_task_run_repo(request: Request):\n    val = getattr(request.app.state, \"scheduled_task_run_repo\", None)\n    if val is None:\n        raise HTTPException(status_code=503, detail=\"Scheduled task run repo not available\")\n    return val\n\n\ndef get_scheduled_task_service(request: Request):","sourceCodeStart":622,"sourceCodeEnd":658,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/deps.py#L622-L658","documentation":"HTTP 503 from get_thread_store() when request.app.state.thread_store is None. The thread metadata store (SQL or memory-backed) is created during Gateway lifespan; this error means thread-persistence infrastructure was never attached, so all thread listing/metadata routes fail.","triggerScenarios":"Any call to thread metadata routes (list threads, get/rename/delete thread metadata) when the thread_store singleton is missing — typically because lifespan bootstrap failed (DB init error) or the route was reached on an app instance without the Gateway lifespan.","commonSituations":"Gateway started while the persistence database was down or its file path unwritable; running routers in isolation (pytest fixtures) without lifespan; deployment where an init container step that creates the DB was skipped.","solutions":["Check startup logs for the thread store init failure inside langgraph_runtime()","Confirm the persistence backend config (config.yaml persistence section) points to a reachable database and the path/URL is correct","Restart the Gateway so lifespan reconstructs and attaches thread_store","In tests, use the app fixture that runs the full lifespan instead of a bare FastAPI() instance"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"// client-side preflight\nconst health = await fetch('/api/health');\nif (!health.ok) throw new Error('Gateway not ready — thread store routes will 503');","typeGuard":null,"tryCatchPattern":"try:\n    threads = await client.list_threads()\nexcept GatewayHTTPError as e:\n    if e.status == 503 and 'Thread metadata store' in e.detail:\n        threads = []  # optional feature unavailable\n    else:\n        raise","preventionTips":["Ensure the persistence DB is up before Gateway start (compose depends_on with healthcheck)","Check /health after deploys before serving user traffic","Never mount Gateway routers without the Gateway lifespan"],"tags":["http-503","threads","persistence","lifespan","gateway"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}