bytedance/deer-flow · error · HTTPException

Failed to create thread checkpoint

Error message

Failed to create thread checkpoint

What it means

Raised when ensure_thread_checkpoint(checkpointer, thread_id) fails while provisioning a checkpoint for the goal flow. The checkpointer (LangGraph SQL checkpointer) must write an initial checkpoint row; any exception from that write is logged with the thread id and returned as a 500 'Failed to create thread checkpoint'.

Source

Thrown at backend/app/gateway/routers/threads.py:612

    record = await thread_store.get(thread_id, **thread_owner_kwargs)
    if record is None and thread_owner_user_id:
        unscoped_record = await thread_store.get(thread_id, user_id=None)
        if unscoped_record is not None:
            if unscoped_record.get("user_id") != thread_owner_user_id:
                await thread_store.update_owner(thread_id, thread_owner_user_id, user_id=None)
            record = await thread_store.get(thread_id, **thread_owner_kwargs)
    if record is None:
        try:
            await thread_store.create(thread_id, metadata={}, **thread_owner_kwargs)
        except Exception:
            logger.exception("Failed to create thread_meta for goal thread %s", sanitize_log_param(thread_id))
            raise HTTPException(status_code=500, detail="Failed to create thread") from None

    try:
        await ensure_thread_checkpoint(checkpointer, thread_id)
    except Exception:
        logger.exception("Failed to create goal checkpoint for thread %s", sanitize_log_param(thread_id))
        raise HTTPException(status_code=500, detail="Failed to create thread checkpoint") from None


# ---------------------------------------------------------------------------
# Endpoints
# ---------------------------------------------------------------------------


@router.delete("/{thread_id}", response_model=ThreadDeleteResponse)
@require_permission("threads", "delete", owner_check=True, require_existing=True)
async def delete_thread_data(thread_id: str, request: Request) -> ThreadDeleteResponse:
    """Delete local persisted filesystem data for a thread.

    Cleans DeerFlow-managed thread directories, removes checkpoint data,
    and removes the thread_meta row from the configured ThreadMetaStore
    (sqlite or memory).
    """
    from app.gateway.deps import get_thread_store

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Check the Gateway log for 'Failed to create goal checkpoint for thread %s' — the chained exception names the driver error.
  2. Run the backend migration step so checkpoints/checkpoint_writes/checkpoint_blobs tables exist and match the installed langgraph-checkpoint version.
  3. Verify checkpointer config in config.yaml (URL, pool size) and database health.
  4. Retry the PUT after the storage issue is fixed; the flow is idempotent for existing checkpoints.
Defensive patterns

Strategy: retry

Try / catch

try { await api.put(`/threads/${id}/goal`, body); }
catch (err) {
  if (err.status === 500 && /checkpoint/i.test(err.detail)) { await waitForDbHealth(); retry(); }
  else throw err;
}

Prevention

When it happens

Trigger: PUT /api/threads/{thread_id}/goal on a fresh thread when checkpoint storage is unavailable (DB down, checkpoint tables missing, serializer errors on initial state), or the checkpoint writer hits a constraint/serialization failure.

Common situations: Checkpointer database not migrated to the LangGraph checkpoint schema after an upgrade; SQLite file locked by a concurrent writer; connection pool exhausted under load; Postgres auth/permissions changed.

Related errors


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