bytedance/deer-flow · error · HTTPException
Thread metadata store not available
Error message
Thread metadata store not available
What it means
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.
Source
Thrown at backend/app/gateway/deps.py:640
get_stream_bridge: Callable[[Request], StreamBridge] = _require("stream_bridge", "Stream bridge")
get_run_manager: Callable[[Request], RunManager] = _require("run_manager", "Run manager")
get_checkpointer: Callable[[Request], Checkpointer] = _require("checkpointer", "Checkpointer")
get_run_event_store: Callable[[Request], RunEventStore] = _require("run_event_store", "Run event store")
get_feedback_repo: Callable[[Request], FeedbackRepository] = _require("feedback_repo", "Feedback")
get_run_store: Callable[[Request], RunStore] = _require("run_store", "Run store")
def get_store(request: Request):
"""Return the global store (may be ``None`` if not configured)."""
return getattr(request.app.state, "store", None)
def get_thread_store(request: Request) -> ThreadMetaStore:
"""Return the thread metadata store (SQL or memory-backed)."""
val = getattr(request.app.state, "thread_store", None)
if val is None:
raise HTTPException(status_code=503, detail="Thread metadata store not available")
return val
def get_scheduled_task_repo(request: Request):
val = getattr(request.app.state, "scheduled_task_repo", None)
if val is None:
raise HTTPException(status_code=503, detail="Scheduled task repo not available")
return val
def get_scheduled_task_run_repo(request: Request):
val = getattr(request.app.state, "scheduled_task_run_repo", None)
if val is None:
raise HTTPException(status_code=503, detail="Scheduled task run repo not available")
return val
def get_scheduled_task_service(request: Request):View on GitHub (pinned to 1dd6ba1acb)
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
Example fix
null
Defensive patterns
Strategy: try-catch
Validate before calling
// client-side preflight
const health = await fetch('/api/health');
if (!health.ok) throw new Error('Gateway not ready — thread store routes will 503'); Try / catch
try:
threads = await client.list_threads()
except GatewayHTTPError as e:
if e.status == 503 and 'Thread metadata store' in e.detail:
threads = [] # optional feature unavailable
else:
raise Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- MCP task repo not available
- {label} not available
- Scheduled task run repo not available
- MCP task service not available
- Thread {thread_id} not found
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/839f1f8fc100d5a5.
Report an issue: GitHub.