bytedance/deer-flow · warning · HTTPException
Could not find an addressable checkpoint before the target u
Error message
Could not find an addressable checkpoint before the target user message
What it means
Raised in _find_base_checkpoint_before_human (HTTP 409, detail _MISSING_REGENERATE_BASE_DETAIL) when the target user message was found in checkpoint history but there is no checkpoint before it (previous_checkpoint is None). The target turn is the very first thing that ever checkpointed in the thread, so there is no earlier addressable checkpoint to replay from.
Source
Thrown at backend/app/gateway/routers/thread_runs.py:559
)
except CheckpointLineageError as exc:
logger.warning(
"Rejected unsafe checkpoint lineage for regenerate thread %s",
sanitize_log_param(thread_id),
exc_info=True,
)
raise HTTPException(status_code=409, detail=_UNSAFE_REGENERATE_LINEAGE_DETAIL) from exc
try:
raw_checkpoints = await accessor.ahistory(base_config, limit=REGENERATE_HISTORY_RAW_SCAN_LIMIT)
checkpoints = [item for item in raw_checkpoints if not _is_duration_only_checkpoint(item)]
except Exception as exc:
logger.exception("Failed to list checkpoints for regenerate thread %s", thread_id)
raise HTTPException(status_code=500, detail="Failed to inspect checkpoint history") from exc
previous_checkpoint, target_found = find_checkpoint_before_message_chronologically(raw_checkpoints, human_message_id)
if target_found:
if previous_checkpoint is None:
raise HTTPException(
status_code=409,
detail=_MISSING_REGENERATE_BASE_DETAIL,
)
return previous_checkpoint
if len(checkpoints) >= REGENERATE_HISTORY_SCAN_LIMIT:
logger.warning(
"Could not locate target user message %s in recent checkpoint history for thread %s (limit=%s)",
human_message_id,
thread_id,
REGENERATE_HISTORY_SCAN_LIMIT,
)
raise HTTPException(
status_code=409,
detail=(f"Could not locate target user message in recent checkpoint history (limit={REGENERATE_HISTORY_SCAN_LIMIT})"),
)
View on GitHub (pinned to 1dd6ba1acb)
Solutions
- For a first-turn regenerate, resend the (possibly edited) user message as a new run instead of using regenerate-replay semantics.
- Verify the run you are regenerating is not the thread's only/first checkpointed turn; pick a later turn if available.
- If history pruning is enabled, widen retention so a base checkpoint before the target exists.
- Confirm with the checkpoint store listing that at least one earlier checkpoint exists for the thread.
Defensive patterns
Strategy: fallback
Validate before calling
const cps = await listCheckpoints(threadId);
const targetIdx = cps.findIndex(c => c.contains_message_id === humanMessageId);
if (targetIdx <= 0) { // no earlier checkpoint: resend instead of regenerate } Try / catch
try { await regeneratePrepare(threadId, messageId); } catch (e) { if (e.status === 409 && /addressable checkpoint before/.test(e.detail)) { await resendMessage(threadId, editedText); } else throw e; } Prevention
- Detect first-turn regenerates client-side and offer 'resend' instead
- Widen checkpoint retention for threads users will revisit
When it happens
Trigger: Regenerating the first user turn of a thread: find_checkpoint_before_message_chronologically locates the target but has no preceding checkpoint to return; all earlier checkpoints were duration-only stubs and got filtered; thread history was pruned down to the target turn.
Common situations: Fresh thread where the user immediately regenerates the first response; aggressive checkpoint retention keeping only recent history.
Related errors
- Checkpoint is missing checkpoint_id
- Could not safely resolve the checkpoint before the target us
- Could not locate target user message in recent checkpoint hi
- Only the latest completed user turn can be edited
- Only completed assistant text turns can be edited
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/c849000018a2695d.
Report an issue: GitHub.