{"record":{"id":"41ec2222c3b7822d","repo":"BerriAI/litellm","slug":"reducto-upload-returned-a-non-json-200-response","errorCode":null,"errorMessage":"Reducto /upload returned a non-JSON 200 response: {response.text}","messagePattern":"Reducto /upload returned a non-JSON 200 response: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/reducto/common.py","lineNumber":69,"sourceCode":"        _raise_bad_request(\"Invalid Reducto data URI provided.\", model=model)\n\n    if \";base64\" not in header:\n        _raise_bad_request(\"Reducto only supports base64-encoded data URIs.\", model=model)\n\n    mime: Final = header.removeprefix(\"data:\").split(\";\")[0] or \"application/octet-stream\"\n    try:\n        raw_bytes: Final = base64.b64decode(encoded, validate=True)\n    except (binascii.Error, ValueError):\n        _raise_bad_request(\"Invalid Reducto base64 payload provided.\", model=model)\n\n    return None, raw_bytes, mime\n\n\ndef _extract_file_id_from_upload_response(response: Any) -> str:\n    try:\n        payload: Final = response.json()\n    except ValueError as exc:\n        raise ValueError(f\"Reducto /upload returned a non-JSON 200 response: {response.text}\") from exc\n    file_id: Final = (payload or {}).get(\"file_id\") if isinstance(payload, dict) else None\n    if not isinstance(file_id, str) or not file_id:\n        raise ValueError(f\"Reducto /upload returned 200 without a file_id; got payload={payload}\")\n    return file_id\n\n\ndef upload_bytes_sync(\n    raw_bytes: bytes,\n    mime: str | None,\n    api_key: str,\n    api_base: str | None,\n) -> str:\n    import litellm\n\n    response: Final = litellm.module_level_client.post(\n        url=\"{}{}\".format(_normalize_api_base(api_base), \"/upload\"),\n        headers={\"Authorization\": f\"Bearer {api_key}\"},\n        files={\"file\": (\"document\", raw_bytes, mime or \"application/octet-stream\")},","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/reducto/common.py#L51-L87","documentation":"Response-shape guard after a Reducto /upload call: the HTTP status was 200 but response.json() raised, meaning the body is not JSON (unexpected gateway/content response), and the raw text is surfaced for diagnosis.","triggerScenarios":"Triggered when the Reducto /upload endpoint returns HTTP 200 with a body that is not valid JSON.","commonSituations":"See trigger scenarios.","solutions":["The Reducto /upload endpoint returned non-JSON content; check api_base and proxy configuration.","Verify the Reducto server version and that the upload endpoint is correct."],"exampleFix":"# curl the /upload endpoint manually and inspect the raw body.","handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}