{"record":{"id":"07a0c97c5f13b4d7","repo":"bytedance/deer-flow","slug":"thread-thread-id-not-found-07a0c9","errorCode":null,"errorMessage":"Thread {thread_id} not found","messagePattern":"Thread (.+?) not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"warning","filePath":"backend/app/gateway/routers/threads.py","lineNumber":796,"sourceCode":"        thread_id=thread_id,\n        status=\"idle\",\n        created_at=now,\n        updated_at=now,\n        metadata=body.metadata,\n    )\n\n\n@router.post(\"/{thread_id}/branches\", response_model=ThreadBranchResponse)\n@require_permission(\"threads\", \"write\", owner_check=True, require_existing=True)\nasync def branch_thread(thread_id: ThreadId, body: ThreadBranchRequest, request: Request) -> ThreadBranchResponse:\n    \"\"\"Create a new main-thread branch from a completed assistant turn.\"\"\"\n    from app.gateway.deps import get_thread_store\n\n    thread_store = get_thread_store(request)\n\n    source_record = await thread_store.get(thread_id)\n    if source_record is None:\n        raise HTTPException(status_code=404, detail=f\"Thread {thread_id} not found\")\n\n    source_metadata = source_record.get(\"metadata\") or {}\n    if source_metadata.get(_SIDECAR_METADATA_KEY) is True:\n        raise HTTPException(status_code=409, detail=\"Branching is only available in the main conversation.\")\n    source_accessor, source_config = build_checkpoint_state_accessor(\n        request,\n        thread_id=thread_id,\n        assistant_id=source_record.get(\"assistant_id\"),\n    )\n\n    target_message_ids = {body.message_id, *body.message_ids}\n    snapshot = await _find_branch_checkpoint(source_accessor, source_config, target_message_ids)\n    parent_checkpoint_id = _checkpoint_id(snapshot)\n    if not parent_checkpoint_id:\n        raise HTTPException(status_code=409, detail=\"This turn can no longer be branched from.\")\n    target_human = _branch_target_human_message(_checkpoint_messages(snapshot), target_message_ids)\n    target_human_id = _message_id(target_human)\n    if not target_human_id:","sourceCodeStart":778,"sourceCodeEnd":814,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/routers/threads.py#L778-L814","documentation":"404 from POST /api/threads/{thread_id}/branches when thread_store.get(thread_id) returns None — no thread_meta record exists for the source thread. The endpoint requires a persisted main-conversation thread before it can branch from one of its turns.","triggerScenarios":"Branching a thread_id that was never created via POST /threads, was deleted, belongs to another owner (store scoped by user), or exists only as checkpoints with no thread_meta row.","commonSituations":"Frontend keeps a stale thread id after the thread was deleted or its ownership changed; calling the branch API against a sidecar/generated thread that never got a meta record; typos or truncated UUIDs in the URL.","solutions":["Confirm the thread exists: GET /api/threads/{thread_id} returns 200 before branching.","If it was deleted, re-create it or branch from an existing thread.","Check you are authenticated as the thread's owner user when the store is user-scoped.","Regenerate/repair the client's thread list so it only offers branchable ids."],"exampleFix":"// before\nawait fetch(`/api/threads/${staleId}/branches`, {method: 'POST', body: JSON.stringify({message_id: id})});\n// after\nconst exists = await fetch(`/api/threads/${staleId}`).ok;\nif (!exists) { /* refresh thread list, pick a live thread */ }\nawait fetch(`/api/threads/${staleId}/branches`, {method: 'POST', body: JSON.stringify({message_id: id})});","handlingStrategy":"validation","validationCode":"const res = await fetch(`/api/threads/${id}`);\nif (res.status === 404) { /* drop branch affordance; refresh thread list */ }","typeGuard":null,"tryCatchPattern":"try { await api.post(`/api/threads/${id}/branches`, {message_id}); }\ncatch (err) { if (err.status === 404) removeThreadFromUI(id); else throw err; }","preventionTips":["Only show the branch action for threads returned by the thread list API.","Re-verify existence after tab regained focus or reconnect (thread may have been deleted)."],"tags":["threads","branching","http-404","not-found"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}