bytedance/deer-flow · warning · HTTPException
Thread {thread_id} has no checkpoint
Error message
Thread {thread_id} has no checkpoint What it means
Raised in _prepare_regenerate_payload (HTTP 404) when the thread's latest checkpoint exists as a tuple but its configurable carries no checkpoint_id. Practically: the thread has no addressable checkpoint state (no completed graph step), so there is nothing to regenerate from.
Source
Thrown at backend/app/gateway/routers/thread_runs.py:640
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:
target_message = messages[target_index]
if not _is_visible_ai_message(target_message):
raise HTTPException(status_code=409, detail="Only visible assistant messages can be regenerated")View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Send at least one message and let a run complete before offering regenerate.
- Confirm via GET thread state that a checkpoint_id is present.
- If history was wiped intentionally, treat the thread as new and start a fresh run.
Example fix
// before
regeneratePrepare(threadId, messageId);
// after
const st = await getThreadState(threadId);
if (!st.checkpoint_id) throw new Error('Nothing to regenerate yet');
regeneratePrepare(threadId, messageId); Defensive patterns
Strategy: validation
Validate before calling
const st = await getThreadState(threadId);
if (!st?.checkpoint_id) { notify('Send a message first'); return; } Type guard
function threadHasCheckpoint(st: {checkpoint_id?: string | null}): boolean {
return typeof st.checkpoint_id === 'string' && st.checkpoint_id.length > 0;
} Try / catch
try { await regeneratePrepare(threadId, messageId); } catch (e) { if (e.status === 404 && /has no checkpoint/.test(e.detail)) { hideRegenerateButton(); } else throw e; } Prevention
- Show regenerate only after first completed response
- Check thread state before enabling rewind actions
When it happens
Trigger: Regenerate-prepare on a brand-new thread with zero runs; a run that was created but crashed before its first checkpoint write; checkpoint store emptied for the thread.
Common situations: UI shows a regenerate button before the first response; user deleted thread history; run interrupted pre-checkpoint.
Related errors
- Checkpoint is missing checkpoint_id
- Could not safely resolve the checkpoint before the target us
- Could not find an addressable checkpoint before the target u
- Could not locate target user message in recent checkpoint hi
- Message {message_id} not found
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/4c5b1228c861f0cd.
Report an issue: GitHub.