{"record":{"id":"b69fee9f98e38e0e","repo":"fishaudio/fish-speech","slug":"unsupported-media-type","errorCode":null,"errorMessage":"Unsupported Media Type","messagePattern":"Unsupported Media Type","errorType":"http","errorClass":"HTTPException","httpStatus":415,"severity":"error","filePath":"tools/server/api_utils.py","lineNumber":64,"sourceCode":"class MsgPackRequest(HttpRequest):\n    async def data(\n        self,\n    ) -> Annotated[\n        Any,\n        ContentType(\"application/msgpack\"),\n        ContentType(\"application/json\"),\n        ContentType(\"multipart/form-data\"),\n    ]:\n        if self.content_type == \"application/msgpack\":\n            return ormsgpack.unpackb(await self.body)\n\n        elif self.content_type == \"application/json\":\n            return await self.json\n\n        elif self.content_type == \"multipart/form-data\":\n            return await self.form\n\n        raise HTTPException(\n            HTTPStatus.UNSUPPORTED_MEDIA_TYPE,\n            headers={\n                \"Accept\": \"application/msgpack, application/json, multipart/form-data\"\n            },\n        )\n\n\nasync def inference_async(req: ServeTTSRequest, engine: TTSInferenceEngine):\n    for chunk in inference(req, engine):\n        print(\"Got chunk\")\n        if isinstance(chunk, bytes):\n            yield chunk\n\n\nasync def buffer_to_async_generator(buffer):\n    yield buffer\n\n","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/fishaudio/fish-speech/blob/befe4001745417f8c42131739d862b8a6fdbd15a/tools/server/api_utils.py#L46-L82","documentation":"The server's request-body parser only supports application/msgpack, application/json, and multipart/form-data; any other Content-Type raises 415 Unsupported Media Type with an Accept header listing what it will take.","triggerScenarios":"POSTing to an endpoint with Content-Type: text/plain, application/x-www-form-urlencoded, or a missing/misspelled content type.","commonSituations":"Custom HTTP clients defaulting to form encoding; curl without -H 'Content-Type: application/json'; proxies/gateways rewriting the header.","solutions":["Set Content-Type: application/json (or msgpack for binary efficiency, multipart for file uploads)","For curl add -H 'Content-Type: application/json' alongside --data","Inspect the response's Accept header to see accepted types"],"exampleFix":"# before\ncurl -X POST url/v1/tts --data '{...}'\n# after\ncurl -X POST url/v1/tts -H 'Content-Type: application/json' --data '{...}'","handlingStrategy":"validation","validationCode":"assert req.headers.get(\"content-type\", \"\").split(\";\")[0] in {\n    \"application/msgpack\", \"application/json\", \"multipart/form-data\"\n}","typeGuard":null,"tryCatchPattern":"if resp.status_code == 415:\n    resp = requests.post(url, json=payload)  # retry with correct content type","preventionTips":["Always set Content-Type explicitly in custom clients","Use the provided api_client.py which sets it correctly"],"tags":["http","content-type","api-server"],"backgroundTag":"unsupported-media-type","analyzedSha":"befe4001745417f8c42131739d862b8a6fdbd15a","analyzedAt":"2026-08-27T21:31:45.703Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}