{"record":{"id":"af95f471d66533c8","repo":"huggingface/transformers","slug":"expected-model-name-as-string","errorCode":null,"errorMessage":"Expected model name as string","messagePattern":"Expected model name as string","errorType":"http","errorClass":"HTTPException","httpStatus":422,"severity":"error","filePath":"src/transformers/cli/serving/transcription.py","lineNumber":112,"sourceCode":"        \"\"\"\n        from transformers.utils.import_utils import is_librosa_available, is_multipart_available\n\n        if not is_librosa_available():\n            raise ImportError(\"Missing librosa dependency for audio transcription. Install with `pip install librosa`\")\n        if not is_multipart_available():\n            raise ImportError(\n                \"Missing python-multipart dependency for file uploads. Install with `pip install python-multipart`\"\n            )\n\n        async with request.form() as form:\n            self._validate_request(set(form.keys()))\n            file_field = form[\"file\"]\n            if isinstance(file_field, str):\n                raise HTTPException(status_code=422, detail=\"Expected file upload, got string\")\n            file_bytes = await file_field.read()\n            model = form[\"model\"]\n            if not isinstance(model, str):\n                raise HTTPException(status_code=422, detail=\"Expected model name as string\")\n            stream = str(form.get(\"stream\", \"false\")).lower() == \"true\"\n\n        model_id_and_revision = self.model_manager.process_model_name(model)\n        audio_model, audio_processor = self.model_manager.load_model_and_processor(model_id_and_revision)\n        base_manager = self.generation_state.get_manager(model_id_and_revision)\n        if not isinstance(base_manager, GenerateManager):\n            raise HTTPException(status_code=400, detail=\"Audio transcription requires sequential generation (not CB)\")\n        gen_manager = base_manager\n        audio_inputs = self._prepare_audio_inputs(file_bytes, audio_processor, audio_model)\n\n        if stream:\n            return self._streaming(gen_manager, audio_model, audio_processor, audio_inputs)\n        return await self._non_streaming(gen_manager, audio_model, audio_processor, audio_inputs)\n\n    @staticmethod\n    def _prepare_audio_inputs(\n        file_bytes: bytes, audio_processor: \"ProcessorMixin\", audio_model: \"PreTrainedModel\"\n    ) -> dict:","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/cli/serving/transcription.py#L94-L130","documentation":"HTTP 422 from the transcription handler when the multipart 'model' field is not a string. Multipart values are strings or UploadFile objects; this check rejects requests that upload a file under the 'model' key or otherwise send a non-text part, before process_model_name would fail confusingly.","triggerScenarios":"Including 'model' as a file part (files={'model': ...}) instead of a form field; clients that serialize the model name into a Blob; multipart bodies where the model part carries a filename disposition making it an UploadFile.","commonSituations":"Frontend code that wraps every value in FormData.append(name, new Blob([...])) instead of plain strings; ported code from an API that accepted model files by upload.","solutions":["Send 'model' as a plain text form field: data={'model': 'openai/whisper-large-v3'}","Ensure only 'file' is sent as a file part and every other field as text","Inspect the outgoing multipart body (e.g. curl -F model=openai/whisper-large-v3 -F file=@a.wav) to confirm part types"],"exampleFix":"# before\nrequests.post(url, files={'file': fh, 'model': ('model.txt', b'whisper')})\n# after\nrequests.post(url, files={'file': fh}, data={'model': 'openai/whisper-large-v3'})","handlingStrategy":"type-guard","validationCode":"assert isinstance(model_id, str), 'model must be a plain string form field'\nresp = requests.post(url, files={'file': fh}, data={'model': model_id})","typeGuard":"def is_model_field(v) -> bool:\n    return isinstance(v, str) and len(v) > 0  # not a tuple/Blob file part","tryCatchPattern":"if resp.status_code == 422 and 'model name as string' in resp.text:\n    raise ValueError(\"send 'model' as a text form field (data=), not a file part\") from None","preventionTips":["Keep exactly one file part ('file') per request; everything else is a text field","Type-check form values in one shared client helper before dispatch"],"tags":["api","serving","validation","http-422"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}