bytedance/deer-flow · warning · HTTPException

Checkpoint {checkpoint_id} not found

Error message

Checkpoint {checkpoint_id} not found

What it means

HTTP 404 raised when a run references a checkpoint_id that the checkpointer does not return a tuple for — the checkpoint does not exist (or no longer exists) for that thread/namespace. Validation happens before the run starts, so no work is performed.

Source

Thrown at backend/app/gateway/services.py:976

    read_config: dict[str, Any] = {
        "configurable": {
            "thread_id": thread_id,
            "checkpoint_ns": checkpoint_ns,
            "checkpoint_id": str(checkpoint_id),
        }
    }
    if checkpoint_map is not None:
        read_config["configurable"]["checkpoint_map"] = checkpoint_map

    checkpointer = get_checkpointer(request)
    try:
        checkpoint_tuple = await checkpointer.aget_tuple(read_config)
    except Exception as exc:
        logger.exception("Failed to validate checkpoint %s for thread %s", checkpoint_id, sanitize_log_param(thread_id))
        raise HTTPException(status_code=500, detail="Failed to validate checkpoint") from exc
    if checkpoint_tuple is None:
        raise HTTPException(status_code=404, detail=f"Checkpoint {checkpoint_id} not found")

    configurable = config.setdefault("configurable", {})
    if not isinstance(configurable, dict):
        raise HTTPException(status_code=400, detail="request config configurable must be an object")
    configurable["thread_id"] = thread_id
    configurable["checkpoint_ns"] = checkpoint_ns
    configurable["checkpoint_id"] = str(checkpoint_id)
    if checkpoint_map is not None:
        configurable["checkpoint_map"] = checkpoint_map


async def ensure_checkpoint_history_seeded(
    request: Request,
    *,
    thread_id: str,
    assistant_id: str | None,
) -> None:
    """Backfill an empty run-event feed from an existing checkpoint head.

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. List the thread's checkpoints (history endpoint) and use a current checkpoint_id.
  2. If checkpoints were pruned, drop the reference and run from the thread's latest state instead.
  3. Verify the id is copied verbatim (full UUID/hex, no truncation).

Example fix

# before
{"checkpoint_id": "1ef4f797-8335", "input": {...}}

# after
{"checkpoint_id": "1ef4f797-8335-6428-8001-8a1506f3b775", "input": {...}}
Defensive patterns

Strategy: validation

Validate before calling

const cps = await fetch(`/api/threads/${tid}/checkpoints`).then(r => r.json());
const valid = cps.some(c => c.checkpoint_id === payload.checkpoint_id);
if (!valid) delete payload.checkpoint_id; // run from latest state instead

Try / catch

catch 404 'Checkpoint ... not found'; fall back to running without the checkpoint reference or refresh the id from history and retry.

Prevention

When it happens

Trigger: POSTing a run with checkpoint_id from an old conversation snapshot after checkpoints were pruned/cleared; typos in the id; referencing a checkpoint belonging to a different thread or checkpoint_ns.

Common situations: Checkpoint retention/TTL deleting old snapshots; client caching checkpoint ids across a thread reset; ids truncated or altered in transit.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/93f9a9cf04ae2c28. Report an issue: GitHub.