{"record":{"id":"2658352080a694a7","repo":"odysseus-dev/odysseus","slug":"text-must-be-a-string","errorCode":null,"errorMessage":"text must be a string","messagePattern":"text must be a string","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"routes/upload_routes.py","lineNumber":521,"sourceCode":"        if not info:\n            raise HTTPException(404, \"File not found\")\n        auth_mgr = getattr(request.app.state, \"auth_manager\", None)\n        auth_configured = bool(auth_mgr and auth_mgr.is_configured)\n        current_user = effective_user(request)\n        file_owner = info.get(\"owner\")\n        if auth_configured:\n            if not current_user:\n                raise HTTPException(403, \"Access denied\")\n            if file_owner != current_user and not auth_mgr.is_admin(current_user):\n                raise HTTPException(404, \"File not found\")\n        _resolve_upload_path(file_id)\n        try:\n            body = await request.json()\n        except json.JSONDecodeError:\n            raise HTTPException(400, \"Request body must be valid JSON\")\n        text = (body or {}).get(\"text\", \"\")\n        if not isinstance(text, str):\n            raise HTTPException(400, \"text must be a string\")\n        with open(_vision_cache_path(file_id), \"w\", encoding=\"utf-8\") as f:\n            f.write(text)\n        _sync_gallery_caption_for_upload(info, file_owner or current_user, text)\n        return {\"ok\": True}\n\n    async def periodic_rate_limit_cleanup():\n        \"\"\"Background task to run cleanup every hour\"\"\"\n        while True:\n            await asyncio.sleep(3600)\n            upload_handler.cleanup_rate_limits()\n    \n    return router, periodic_rate_limit_cleanup\n","sourceCodeStart":503,"sourceCodeEnd":534,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/routes/upload_routes.py#L503-L534","documentation":"Error \"text must be a string\" thrown in odysseus-dev/odysseus.","triggerScenarios":"Triggered when the corresponding server-side validation or runtime check at the recorded location rejects the request or operation and returns this error message to the caller.","commonSituations":"See trigger scenarios.","solutions":["Send the text field as a string.","Fix the client to not send objects or numbers for text."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}