{"record":{"id":"d093828a0328ff69","repo":"HKUDS/Vibe-Trading","slug":"format-must-be-html-or-pdf","errorCode":null,"errorMessage":"format must be html or pdf","messagePattern":"format must be html or pdf","errorType":"validation","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"agent/src/api/uploads_routes.py","lineNumber":105,"sourceCode":"        host = _sys.modules.get(\"api_server\") or _sys.modules.get(\"agent.api_server\")\n        return host.MAX_UPLOAD_SIZE if host else MAX_UPLOAD_SIZE\n\n    def _host_chunk_size() -> int:\n        import sys as _sys\n\n        host = _sys.modules.get(\"api_server\") or _sys.modules.get(\"agent.api_server\")\n        return host._UPLOAD_CHUNK_SIZE if host else _UPLOAD_CHUNK_SIZE\n\n    @app.get(\"/shadow-reports/{shadow_id}\", dependencies=[Depends(require_auth)])\n    async def get_shadow_report(shadow_id: str, format: str = \"html\"):\n        \"\"\"Serve a rendered Shadow Account report.\n\n        Reports live under ``~/.vibe-trading/shadow_reports/<shadow_id>.{html,pdf}``.\n        \"\"\"\n        if not _SHADOW_ID_RE.match(shadow_id):\n            raise HTTPException(status_code=400, detail=\"invalid shadow_id\")\n        if format not in (\"html\", \"pdf\"):\n            raise HTTPException(status_code=400, detail=\"format must be html or pdf\")\n\n        reports_dir = Path.home() / \".vibe-trading\" / \"shadow_reports\"\n        path = reports_dir / f\"{shadow_id}.{format}\"\n        if not path.exists():\n            raise HTTPException(status_code=404, detail=f\"Shadow report not found: {shadow_id}.{format}\")\n\n        media_type = \"text/html; charset=utf-8\" if format == \"html\" else \"application/pdf\"\n        return FileResponse(\n            path,\n            media_type=media_type,\n            headers={\"Content-Disposition\": f'inline; filename=\"{shadow_id}.{format}\"'},\n        )\n\n    @app.post(\"/upload\", dependencies=[Depends(require_auth)])\n    async def upload_file(file: UploadFile):\n        \"\"\"Upload any document or data file (max 50MB).\n\n        Accepts most common formats: PDF, Word, Excel, PowerPoint, images,","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/api/uploads_routes.py#L87-L123","documentation":"The shadow report endpoint only serves HTML and PDF formats; any other `format` value is rejected with 400 before file lookup.","triggerScenarios":"GET /uploads/shadow-report?shadow_id=X&format=json or format=md; also 'HTML' (uppercase) fails the exact string match.","commonSituations":"Clients defaulting to json, typos like 'pd', or locale-casing differences where the caller sends 'HTML' instead of 'html'.","solutions":["Use format=html or format=pdf exactly (lowercase)","Normalize the format value to lowercase client-side"],"exampleFix":"// before\n?format=HTML\n// after\n?format=html","handlingStrategy":"validation","validationCode":"fmt = fmt.lower()\nassert fmt in ('html','pdf'), 'format must be html or pdf'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lowercase the format value before the request"],"tags":["validation","uploads","api"],"backgroundTag":"request-parameter-validation-failed","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}