{"record":{"id":"548af6abb1c4e99a","repo":"HKUDS/DeepTutor","slug":"day-must-be-yyyy-mm-dd","errorCode":null,"errorMessage":"day must be YYYY-MM-DD","messagePattern":"day must be YYYY-MM-DD","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"deeptutor/api/routers/memory.py","lineNumber":714,"sourceCode":"async def clear_trace(surface: str):\n    surf = _validate_surface(surface)\n    removed = 0\n    for path in paths.trace_dir(surf).glob(\"*.jsonl\"):\n        try:\n            path.unlink()\n            removed += 1\n        except OSError:\n            continue\n    return {\"surface\": surf, \"removed_files\": removed}\n\n\n@router.delete(\"/trace/{surface}/day/{day}\")\nasync def clear_trace_day(surface: str, day: str):\n    surf = _validate_surface(surface)\n    try:\n        parsed = date_cls.fromisoformat(day)\n    except ValueError:\n        raise HTTPException(status_code=400, detail=\"day must be YYYY-MM-DD\")\n    path = paths.trace_file(surf, parsed)\n    if not path.exists():\n        raise HTTPException(status_code=404, detail=\"no trace for that day\")\n    try:\n        path.unlink()\n    except OSError as exc:\n        raise HTTPException(status_code=500, detail=str(exc))\n    return {\"surface\": surf, \"day\": day, \"deleted\": True}\n\n\n# ── Snapshot (L1 workspace mirror) ───────────────────────────────────────\n\n\n@router.get(\"/snapshot/{surface}\")\nasync def get_snapshot(surface: str):\n    \"\"\"Return the current entity list for ``surface`` from workspace.\n\n    Snapshot is always derived live from workspace at call time. The response","sourceCodeStart":696,"sourceCodeEnd":732,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/api/routers/memory.py#L696-L732","documentation":"HTTP 400 from DELETE /memory/trace/{surface}/day/{day} when the day path parameter cannot be parsed by date.fromisoformat — it must be an exact ISO calendar date (YYYY-MM-DD).","triggerScenarios":"Passing dates like '2026-8-7' (no zero padding), '20260807', '07-08-2026', or any non-date string in the day segment.","commonSituations":"Client-side date formatting that omits zero-padding (common with JS getMonth()/getDate()), locale-formatted dates, or Unix timestamps passed instead of ISO dates.","solutions":["Format the date as an ISO string before the request: in JS use date.toISOString().slice(0,10); in Python use date.isoformat()","Validate the day segment with a ^\\d{4}-\\d{2}-\\d{2}$ regex (plus a real calendar check) before calling","Add a shared date-formatting util so all call sites emit ISO dates"],"exampleFix":"// before\nconst day = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;\n// after\nconst day = d.toISOString().slice(0, 10); // '2026-08-27'","handlingStrategy":"validation","validationCode":"function isoDay(d: Date): string { return d.toISOString().slice(0, 10); }\nif (!/^\\d{4}-\\d{2}-\\d{2}$/.test(day)) throw new Error('bad date');","typeGuard":"function isIsoDay(s: string): boolean { return /^\\d{4}-\\d{2}-\\d{2}$/.test(s) && !isNaN(Date.parse(s)); }","tryCatchPattern":"try { await clearTraceDay(surface, day); } catch (e) { if (e.status === 400) throw new Error(`invalid day format: ${day}`); else throw e; }","preventionTips":["Always format with toISOString().slice(0,10) or date.isoformat()","Never build date strings from getMonth()/getDate() without padding"],"tags":["memory","trace","http-400","date-validation","iso-date"],"backgroundTag":"date-validation-failed","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}