HKUDS/DeepTutor · error · HTTPException

No records provided

Error message

No records provided

What it means

Raised by the POST /progress/{book_id}/generate-from-notebook endpoint when the request body contains no records. The endpoint converts notebook records into a generated learning plan, so an empty records list means there is nothing to generate from, and the server rejects it with a 400 before calling the LLM.

Source

Thrown at deeptutor/api/routers/mastery_path.py:390


class NotebookRecordInput(BaseModel):
    id: str
    type: str = "note"
    title: str = ""
    output: str = ""


class GenerateFromNotebookRequest(BaseModel):
    notebook_id: str
    records: list[NotebookRecordInput]


@router.post("/progress/{book_id}/generate-from-notebook")
async def generate_from_notebook(book_id: str, body: GenerateFromNotebookRequest):
    _validate_book_id(book_id)
    if not body.records:
        raise HTTPException(status_code=400, detail="No records provided")

    records_data = [
        {
            "type": html.escape(r.type[:50], quote=False),
            "title": html.escape(r.title[:200], quote=False),
            "output": html.escape(r.output[:500], quote=False),
        }
        for r in body.records[:20]
    ]
    records_json = json.dumps(records_data, ensure_ascii=False)
    from deeptutor.services.llm import complete

    language = get_response_language()
    system_prompt, prompt = learning_prompts.notebook_generation_prompts(language, records_json)
    response = await complete(prompt=prompt, system_prompt=system_prompt)
    # LLMs commonly fence/slightly-malform JSON; use the shared fence-stripping
    # repair parser instead of bare json.loads so the common case isn't a 502.
    data = parse_json_response(response, fallback=None)

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Ensure the client collects at least one notebook record before submitting the request
  2. Check client-side state: verify the records array is populated (e.g. notebook entries exist for the current book)
  3. Add a UI guard/disable on the submit button when the notebook is empty
  4. If records are being transformed client-side, log the payload before sending to confirm they survive filtering

Example fix

// before
await fetch(`/progress/${bookId}/generate-from-notebook`, {
  method: "POST",
  body: JSON.stringify({ records: notebookRecords }), // notebookRecords is []
});

// after
if (notebookRecords.length === 0) {
  alert("Add at least one notebook record first");
  return;
}
await fetch(`/progress/${bookId}/generate-from-notebook`, {
  method: "POST",
  body: JSON.stringify({ records: notebookRecords }),
});
Defensive patterns

Strategy: validation

Validate before calling

if (!records || records.length === 0) {
  throw new Error('Cannot generate from notebook: no records');
}
await api.post(`/progress/${bookId}/generate-from-notebook`, { records });

Type guard

function hasRecords(req: GenerateFromNotebookRequest): boolean {
  return Array.isArray(req.records) && req.records.length > 0;
}

Prevention

When it happens

Trigger: POST /progress/{book_id}/generate-from-notebook with a GenerateFromNotebookRequest whose records array is empty ([]) or omitted entirely (defaults to empty).

Common situations: Frontend submits the form before the user has created any notebook entries; the notebook feature being tested against a fresh account with no records; a client-side bug filtering out all records before submission.

Related errors


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