HKUDS/DeepTutor · warning · HTTPException

Record not found

Error message

Record not found

What it means

404 raised when notebook_manager.remove_record returns falsy, meaning either the notebook or the record id passed on the path does not exist in the store. Deletion is only attempted after both ids resolve; otherwise the endpoint aborts with 'Record not found'.

Source

Thrown at deeptutor/api/routers/notebook.py:381

    )


@router.delete("/{notebook_id}/records/{record_id}")
async def remove_record(notebook_id: str, record_id: str):
    """
    Remove record from notebook

    Args:
        notebook_id: Notebook ID
        record_id: Record ID

    Returns:
        Deletion result
    """
    try:
        success = notebook_manager.remove_record(notebook_id, record_id)
        if not success:
            raise HTTPException(status_code=404, detail="Record not found")
        return {"success": True, "message": "Record removed successfully"}
    except HTTPException:
        raise
    except NotebookCorruptedError as exc:
        raise _unreadable(exc)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/{notebook_id}/records/{record_id}")
async def update_record(notebook_id: str, record_id: str, request: UpdateRecordRequest):
    """Update an existing notebook record in place."""
    try:
        # Forward only what the client actually sent. Passing every field
        # unconditionally would hand `kb_name=None` to the service on every
        # request and clear the record's knowledge-base link as a side effect
        # of renaming it; the service's sentinel default only works if an
        # omitted field never reaches it.

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Re-fetch the notebook's records to get current ids before deleting
  2. Treat 404 on delete as idempotent success if the record is already gone
  3. Confirm notebook_id is correct and the notebook still exists

Example fix

// before
await client.delete(f"/notebook/{nb}/records/{rid}")  # raises 404
// after
resp = await client.delete(f"/notebook/{nb}/records/{rid}")
if resp.status_code == 404:
    pass  # already removed; treat as success
Defensive patterns

Strategy: try-catch

Validate before calling

resp = await client.get(f"/notebook/{nb}/records")
exists = any(r["id"] == rid for r in resp.json()["records"])
if not exists:
    return  # already gone

Try / catch

resp = await client.delete(f"/notebook/{nb}/records/{rid}")
if resp.status_code == 404:
    pass  # idempotent delete

Prevention

When it happens

Trigger: DELETE (or the remove_record route) with a record_id that was already deleted, a notebook_id that doesn't exist, or ids copied from a different environment/data directory.

Common situations: Double-submit of a delete button where the first request already removed the record; UI holding stale record ids after another client removed them; data directory reset between listing and deleting.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/555efbdda5388bcc. Report an issue: GitHub.