bytedance/deer-flow · error · HTTPException
Failed to read thread goal
Error message
Failed to read thread goal
What it means
500 from GET /threads/{thread_id}/goal when read_thread_goal(checkpointer, thread_id) raises — reading the goal node's state out of the checkpointer failed with an unexpected exception. The traceback is logged with the thread id; a thread with no goal returns a null goal, not an error, so this is strictly a storage/read failure.
Source
Thrown at backend/app/gateway/routers/threads.py:1084
thread_id=thread_id,
status=status,
created_at=coerce_iso(record.get("created_at", "")),
updated_at=coerce_iso(record.get("updated_at", "")),
metadata=record.get("metadata", {}),
values=serialize_channel_values_for_api(snapshot.values),
)
@router.get("/{thread_id}/goal", response_model=ThreadGoalResponse)
@require_permission("threads", "read", owner_check=True)
async def get_thread_goal(thread_id: ThreadId, request: Request) -> ThreadGoalResponse:
"""Return the active Claude-style goal for a thread, if any."""
checkpointer = get_checkpointer(request)
try:
goal = await read_thread_goal(checkpointer, thread_id)
except Exception:
logger.exception("Failed to read goal for thread %s", sanitize_log_param(thread_id))
raise HTTPException(status_code=500, detail="Failed to read thread goal") from None
return ThreadGoalResponse(goal=goal)
@router.put("/{thread_id}/goal", response_model=ThreadGoalResponse)
@require_permission("threads", "write", owner_check=True)
async def set_thread_goal(thread_id: ThreadId, body: ThreadGoalRequest, request: Request) -> ThreadGoalResponse:
"""Set or replace the active goal for a thread.
``/chats/new`` pages already hold a generated UUID before the first run, so
this endpoint creates the missing thread checkpoint on demand.
"""
checkpointer = get_checkpointer(request)
try:
goal = build_goal_state(body.objective, max_continuations=body.max_continuations)
async with reserve_checkpoint_write(request, thread_id, user_id=get_effective_user_id()):
await _ensure_thread_for_goal(thread_id, request)
await write_thread_goal(checkpointer, thread_id, goal, as_node="goal", create_if_missing=True)
except ValueError as exc:View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Check the 'Failed to read goal for thread %s' traceback for the storage-level cause.
- Restore checkpoint DB health / align serializer versions.
- Retry the GET — it is read-only.
- If the goal blob itself is corrupt, clearing the goal (DELETE /goal) may fail similarly; delete the thread's checkpoints as a last resort.
Defensive patterns
Strategy: retry
Try / catch
try { const {goal} = await api.get(`/api/threads/${id}/goal`); }
catch (err) { if (err.status === 500) { await backoff(); retryOnce(); } else throw err; } // read-only, retry is safe Prevention
- Cache the goal client-side from the PUT response so GETs are rare.
- Treat single-thread 500s as possible corruption; global 500s as outage.
When it happens
Trigger: GET the goal while checkpoint storage is unreachable, the goal state blob fails to deserialize, or the checkpointer raises a non-mode error during aget.
Common situations: DB outage; serializer/checkpoint version mismatch after upgrade; corrupt goal checkpoint row; lock contention with a concurrent run writing the same thread.
Related errors
- Failed to create thread checkpoint
- Failed to create thread
- Failed to create branch
- Failed to get thread
- Failed to delete local thread data.
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/9cf38e298e5feb9b.
Report an issue: GitHub.