HKUDS/DeepTutor · warning · HTTPException
Record or target notebook not found
Error message
Record or target notebook not found
What it means
404 from copy_record when notebook_manager.copy_record returns falsy: either the source record/notebook doesn't exist, or the target_notebook_id in the MoveRecordRequest body doesn't exist. The single message covers both cases.
Source
Thrown at deeptutor/api/routers/notebook.py:425
)
if not updated:
raise HTTPException(status_code=404, detail="Record not found")
return {"success": True, "record": updated}
except HTTPException:
raise
except NotebookCorruptedError as exc:
raise _unreadable(exc)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.post("/{notebook_id}/records/{record_id}/copy")
async def copy_record(notebook_id: str, record_id: str, request: MoveRecordRequest):
"""Duplicate a record into another notebook under a fresh id."""
try:
copied = notebook_manager.copy_record(notebook_id, record_id, request.target_notebook_id)
if not copied:
raise HTTPException(status_code=404, detail="Record or target notebook not found")
return {"success": True, "record": copied}
except HTTPException:
raise
except NotebookCorruptedError as exc:
raise _unreadable(exc)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.post("/{notebook_id}/records/{record_id}/move")
async def move_record(notebook_id: str, record_id: str, request: MoveRecordRequest):
"""Move a record from this notebook into another one."""
try:
moved = notebook_manager.move_record(notebook_id, record_id, request.target_notebook_id)
if not moved:
raise HTTPException(status_code=404, detail="Record or target notebook not found")
return {"success": True, "record": moved}
except HTTPException:View on GitHub (pinned to 3e82f13042)
Solutions
- Verify both notebook ids exist via GET /notebooks before copying
- Refresh the source record list to confirm record_id is still present
- Create the target notebook first if it doesn't exist
Example fix
// before
await client.post(f"/notebook/{nb}/records/{rid}/copy", json={"target_notebook_id": "ghost"})
// after
await client.post("/notebook/create", json={"name": "Target"})
tid = (await client.get("/notebooks")).json()["notebooks"][-1]["id"]
await client.post(f"/notebook/{nb}/records/{rid}/copy", json={"target_notebook_id": tid}) Defensive patterns
Strategy: validation
Validate before calling
ids = {b["id"] for b in (await client.get("/notebooks")).json()["notebooks"]}
if request_target not in ids:
await create_notebook(request_target) Try / catch
resp = await client.post(copy_url, json=payload)
if resp.status_code == 404:
await refresh_notebooks_and_records() Prevention
- Populate target-notebook pickers from a live /notebooks listing
- Re-check the source record still exists right before copy
When it happens
Trigger: POST /{notebook_id}/records/{record_id}/copy where record_id is stale/removed or request.target_notebook_id names a notebook that was never created or deleted.
Common situations: Target notebook dropdown in the UI holding stale options; copying right after the source record was moved/deleted by another session; typos in target notebook id.
Related errors
- Record not found
- No fields to update
- t("api.partner_not_found_or_not_running")
- t("api.partner_not_running")
- str(exc)
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/d7a2cd0a9558fb77.
Report an issue: GitHub.