HKUDS/DeepTutor · error · HTTPException

day must be YYYY-MM-DD

Error message

day must be YYYY-MM-DD

What it means

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).

Source

Thrown at deeptutor/api/routers/memory.py:714

async def clear_trace(surface: str):
    surf = _validate_surface(surface)
    removed = 0
    for path in paths.trace_dir(surf).glob("*.jsonl"):
        try:
            path.unlink()
            removed += 1
        except OSError:
            continue
    return {"surface": surf, "removed_files": removed}


@router.delete("/trace/{surface}/day/{day}")
async def clear_trace_day(surface: str, day: str):
    surf = _validate_surface(surface)
    try:
        parsed = date_cls.fromisoformat(day)
    except ValueError:
        raise HTTPException(status_code=400, detail="day must be YYYY-MM-DD")
    path = paths.trace_file(surf, parsed)
    if not path.exists():
        raise HTTPException(status_code=404, detail="no trace for that day")
    try:
        path.unlink()
    except OSError as exc:
        raise HTTPException(status_code=500, detail=str(exc))
    return {"surface": surf, "day": day, "deleted": True}


# ── Snapshot (L1 workspace mirror) ───────────────────────────────────────


@router.get("/snapshot/{surface}")
async def get_snapshot(surface: str):
    """Return the current entity list for ``surface`` from workspace.

    Snapshot is always derived live from workspace at call time. The response

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Format the date as an ISO string before the request: in JS use date.toISOString().slice(0,10); in Python use date.isoformat()
  2. Validate the day segment with a ^\d{4}-\d{2}-\d{2}$ regex (plus a real calendar check) before calling
  3. Add a shared date-formatting util so all call sites emit ISO dates

Example fix

// before
const day = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
// after
const day = d.toISOString().slice(0, 10); // '2026-08-27'
Defensive patterns

Strategy: validation

Validate before calling

function isoDay(d: Date): string { return d.toISOString().slice(0, 10); }
if (!/^\d{4}-\d{2}-\d{2}$/.test(day)) throw new Error('bad date');

Type guard

function isIsoDay(s: string): boolean { return /^\d{4}-\d{2}-\d{2}$/.test(s) && !isNaN(Date.parse(s)); }

Try / catch

try { await clearTraceDay(surface, day); } catch (e) { if (e.status === 400) throw new Error(`invalid day format: ${day}`); else throw e; }

Prevention

When it happens

Trigger: Passing dates like '2026-8-7' (no zero padding), '20260807', '07-08-2026', or any non-date string in the day segment.

Common situations: Client-side date formatting that omits zero-padding (common with JS getMonth()/getDate()), locale-formatted dates, or Unix timestamps passed instead of ISO dates.

Related errors


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