{"record":{"id":"c3eefe028ef1d0c8","repo":"HKUDS/DeepTutor","slug":"unsupported-avatar-extension-ext-r","errorCode":null,"errorMessage":"Unsupported avatar extension: {ext!r}","messagePattern":"Unsupported avatar extension: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"deeptutor/multi_user/identity.py","lineNumber":317,"sourceCode":"\ndef _avatar_dir() -> Path:\n    # Resolved lazily so tests that monkeypatch AUTH_DIR keep avatars isolated.\n    return AUTH_DIR / \"avatars\"\n\n\ndef get_avatar_file(user_id: str) -> Path | None:\n    \"\"\"Return the stored avatar image for ``user_id``, or None.\"\"\"\n    for ext in AVATAR_EXTENSIONS:\n        candidate = _avatar_dir() / f\"{user_id}.{ext}\"\n        if candidate.is_file():\n            return candidate\n    return None\n\n\ndef save_avatar_file(user_id: str, data: bytes, ext: str) -> Path:\n    \"\"\"Atomically persist an avatar image, replacing any previous one.\"\"\"\n    if ext not in AVATAR_EXTENSIONS:\n        raise ValueError(f\"Unsupported avatar extension: {ext!r}\")\n    directory = _avatar_dir()\n    directory.mkdir(parents=True, exist_ok=True)\n    target = directory / f\"{user_id}.{ext}\"\n    tmp = directory / f\"{user_id}.{ext}.tmp\"\n    tmp.write_bytes(data)\n    tmp.replace(target)\n    # A re-upload may change the extension; drop stale siblings.\n    for other in AVATAR_EXTENSIONS:\n        if other != ext:\n            (directory / f\"{user_id}.{other}\").unlink(missing_ok=True)\n    return target\n\n\ndef delete_avatar_file(user_id: str) -> None:\n    for ext in AVATAR_EXTENSIONS:\n        (_avatar_dir() / f\"{user_id}.{ext}\").unlink(missing_ok=True)\n\n","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/multi_user/identity.py#L299-L335","documentation":"Error \"Unsupported avatar extension: {ext!r}\" thrown in HKUDS/DeepTutor.","triggerScenarios":"Thrown at deeptutor/multi_user/identity.py:317 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}