HKUDS/DeepTutor · warning · HTTPException
Document not found
Error message
Document not found
What it means
404 raised by _validate_doc_id when the document id fails the strict regex ^[0-9a-f]{8,32}$ (8-32 lowercase hex chars). This is a security guard: the id is used to build a path and DELETE runs rmtree, so traversal like 'a/../../x' must never pass. Malformed ids are intentionally reported as 404, not 400, to avoid leaking the validation rule.
Source
Thrown at deeptutor/api/routers/co_writer.py:527
raise HTTPException(status_code=404, detail="Tool call not found")
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# ─────────────────────────────────────────────────────────────────────────────
# Document CRUD (multi-project Co-Writer)
# ─────────────────────────────────────────────────────────────────────────────
# Storage builds paths as `documents/doc_{doc_id}`; an unvalidated id like
# "a/../../x" would escape the documents root (and DELETE runs rmtree).
_DOC_ID_RE = re.compile(r"^[0-9a-f]{8,32}$")
def _validate_doc_id(doc_id: str) -> str:
if not _DOC_ID_RE.fullmatch(doc_id):
raise HTTPException(status_code=404, detail="Document not found")
return doc_id
class CreateDocumentRequest(BaseModel):
title: str | None = None
content: str = ""
class UpdateDocumentRequest(BaseModel):
title: str | None = None
content: str | None = None
class DocumentResponse(BaseModel):
id: str
title: str
content: str
created_at: floatView on GitHub (pinned to 3e82f13042)
Solutions
- Always use the exact id returned by POST /co-writer/documents
- Check the id matches ^[0-9a-f]{8,32}$ before calling
- If you control id generation, switch to hex ids (e.g. uuid4().hex)
Example fix
// before doc_id = str(uuid.uuid4()) # contains dashes -> 404 // after doc_id = uuid.uuid4().hex # 32 lowercase hex chars
Defensive patterns
Strategy: validation
Validate before calling
import re
DOC_ID_RE = re.compile(r'^[0-9a-f]{8,32}$')
assert DOC_ID_RE.fullmatch(doc_id), 'bad doc id' Type guard
def is_valid_doc_id(doc_id: str) -> bool:
import re
return bool(re.fullmatch(r'[0-9a-f]{8,32}', doc_id)) Prevention
- Only use ids returned by POST /co-writer/documents
- Generate ids as uuid4().hex, never str(uuid4())
- Never build ids from user input
When it happens
Trigger: Calling GET/PUT/DELETE /co-writer/documents/{doc_id} with an id containing uppercase, non-hex characters, slashes/dots, or one shorter than 8 / longer than 32 chars.
Common situations: Client generating its own ids instead of using the id returned by POST /documents, URL-encoding issues that mangle the id, or path-traversal probes.
Related errors
- Operation not found
- Tool call not found
- Invalid folder path
- Model not configured for agent {self.agent_name}. Please act
- Render failed because local LaTeX is missing. Please avoid T
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/31a4954ebd055837.
Report an issue: GitHub.