bytedance/deer-flow · error · HTTPException
Failed to read latest checkpoint
Error message
Failed to read latest checkpoint
What it means
Raised in _prepare_regenerate_payload (HTTP 500) when accessor.aget(latest_config) throws while reading the thread's latest checkpoint. It is a server-side checkpointer failure (storage unreachable, deserialization error), not caused by request payload.
Source
Thrown at backend/app/gateway/routers/thread_runs.py:637
(candidate for candidate in records if getattr(candidate, "run_id", None) == source_run_id),
None,
)
if record is None:
return None
if getattr(record, "thread_id", None) != thread_id:
return None
if _run_status_value(record) != RunStatus.interrupted.value:
return None
return source_run_id
async def _prepare_regenerate_payload(thread_id: str, message_id: str, request: Request) -> RegeneratePrepareResponse:
accessor, latest_config = await build_thread_checkpoint_state_accessor(request, thread_id=thread_id)
try:
latest_checkpoint = await accessor.aget(latest_config)
except Exception as exc:
logger.exception("Failed to read latest checkpoint for regenerate thread %s", thread_id)
raise HTTPException(status_code=500, detail="Failed to read latest checkpoint") from exc
latest_checkpoint_id = _checkpoint_configurable(latest_checkpoint).get("checkpoint_id")
if not latest_checkpoint_id:
raise HTTPException(status_code=404, detail=f"Thread {thread_id} has no checkpoint")
messages = _checkpoint_messages(latest_checkpoint)
target_index = next((i for i, message in enumerate(messages) if _message_id(message) == message_id), None)
if target_index is None:
# A response interrupted during an LLM call can be visible in the live
# stream without ever reaching a checkpoint. The server-stamped run ID
# on the latest user message is the durable link to that partial turn.
previous_human = next(
(message for message in reversed(messages) if _is_visible_human_message(message)),
None,
)
target_run_id = await _find_interrupted_target_run_id(thread_id, previous_human, request) if previous_human is not None else None
if target_run_id is None:
raise HTTPException(status_code=404, detail=f"Message {message_id} not found")
else:View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Read the Gateway log exception 'Failed to read latest checkpoint for regenerate thread' for the root cause.
- Verify checkpointer backend health and credentials.
- Repair or clear the corrupted checkpoint for that thread if deserialization is the cause.
- Retry once the backend recovers.
Defensive patterns
Strategy: retry
Validate before calling
if ((await fetch('/api/health')).status !== 200) { deferCall(); } Try / catch
try { await regeneratePrepare(threadId, messageId); } catch (e) { if (e.status === 500 && /read latest checkpoint/.test(e.detail)) { await backoffRetry(regeneratePrepare, threadId, messageId, 1); } else throw e; } Prevention
- Monitor checkpointer backend health
- Retry 500s with backoff once
- Surface backend logs for deserialization errors
When it happens
Trigger: Checkpoint DB outage or timeout during the regenerate-prepare call; corrupted checkpoint blob that fails deserialization; checkpointer backend restarted mid-request.
Common situations: Transient DB connectivity loss; checkpoint schema drift after an upgrade; misconfigured checkpointer in config.yaml.
Related errors
- Failed to inspect checkpoint history
- Failed to validate checkpoint
- Failed to list agents: {str(e)}
- Failed to get agent: {str(e)}
- Failed to create agent: {str(e)}
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/e388c743c73990bc.
Report an issue: GitHub.