lfnovo/open-notebook · error · HTTPException

Rebuild command not found

Error message

Rebuild command not found

What it means

HTTP 404 raised by the embedding-rebuild status endpoint when surreal_commands returns no command record for the given command_id. It means the rebuild job either never existed, was garbage-collected, or its ID is malformed.

Source

Thrown at api/routers/embedding_rebuild.py:144


@router.get("/rebuild/{command_id}/status", response_model=RebuildStatusResponse)
async def get_rebuild_status(command_id: str):
    """
    Get the status of a rebuild operation.

    Returns:
    - **status**: queued, running, completed, failed
    - **progress**: processed count, total count, percentage
    - **stats**: breakdown by type (sources, notes, insights, failed)
    - **timestamps**: started_at, completed_at
    """
    try:
        # Get command status from surreal_commands
        status = await get_command_status(command_id)

        if not status:
            raise HTTPException(status_code=404, detail="Rebuild command not found")

        # Build response based on status
        response = RebuildStatusResponse(
            command_id=command_id,
            status=status.status,
        )

        # Extract metadata from command result
        if status.result and isinstance(status.result, dict):
            result = status.result

            # Build progress info
            if "total_items" in result and "jobs_submitted" in result:
                total = result["total_items"]
                submitted = result["jobs_submitted"]
                response.progress = RebuildProgress(
                    processed=submitted,
                    total=total,

View on GitHub (pinned to a7de90d38a)

Solutions

  1. Verify the command_id matches the one returned when the rebuild was started (POST endpoint response)
  2. Check that SurrealDB wasn't restarted/reset — surreal_commands state lives there and is lost on reset
  3. If state was lost, simply start a new rebuild and use the new command_id
  4. Inspect surreal_commands table to confirm whether the record exists

Example fix

// before
status = await get_command_status("cmd-123")
// after: confirm the id came from the rebuild start response
resp = await client.post("/api/embedding_rebuild")
command_id = resp.json()["command_id"]
status = await client.get(f"/api/embedding_rebuild/{command_id}/status")
Defensive patterns

Strategy: validation

Validate before calling

resp = await client.get(f"/api/embedding_rebuild/{command_id}/status")
if resp.status_code == 404:
    # command record gone: restart the rebuild rather than polling a dead id
    command_id = (await client.post("/api/embedding_rebuild")).json()["command_id"]

Try / catch

try:
    status = await get_rebuild_status(command_id)
except HTTPException as e:
    if e.status_code == 404:
        command_id = await restart_rebuild()  # get fresh id and stop polling the old one
    else:
        raise

Prevention

When it happens

Trigger: GET /api/embedding_rebuild/{command_id}/status (get_rebuild_status) where get_command_status(command_id) returns None — wrong/stale command_id from a previous rebuild, or the command store (SurrealDB) was reset/wiped between starting the rebuild and polling its status.

Common situations: Frontend polls a rebuild status after a DB reset or after the command record expired; client persists a command_id across server restarts; typo/truncation of the command ID in the URL.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of lfnovo/open-notebook@a7de90d38a (2026-08-27). Data as JSON: /api/errors/826372d08ca86849. Report an issue: GitHub.