{"record":{"id":"2ddfaebde792f46b","repo":"huggingface/transformers","slug":"input-must-be-a-string-or-list","errorCode":null,"errorMessage":"'input' must be a string or list","messagePattern":"'input' must be a string or list","errorType":"http","errorClass":"HTTPException","httpStatus":422,"severity":"error","filePath":"src/transformers/cli/serving/response.py","lineNumber":498,"sourceCode":"            - **Multi-turn list** — messages and tool call items (``function_call``,\n              ``function_call_output``) from a previous response, converted via\n              :meth:`_normalize_response_items`.\n\n        If ``instructions`` is present, it is prepended as a system message.\n        \"\"\"\n        inp = body[\"input\"]\n        instructions = body.get(\"instructions\")\n\n        if isinstance(inp, str):\n            messages = [{\"role\": \"user\", \"content\": inp}]\n        elif isinstance(inp, list):\n            if inp and \"role\" not in inp[0]:\n                # Flat content list (single-turn, e.g. input_text/input_image)\n                messages = [{\"role\": \"user\", \"content\": inp}]\n            else:\n                messages = ResponseHandler._normalize_response_items(inp)\n        else:\n            raise HTTPException(status_code=422, detail=\"'input' must be a string or list\")\n\n        # Prepend instructions as a system message\n        if instructions:\n            if messages and messages[0][\"role\"] == \"system\":\n                messages[0][\"content\"] = instructions\n            else:\n                messages.insert(0, {\"role\": \"system\", \"content\": instructions})\n\n        return messages\n\n    @staticmethod\n    def _normalize_response_items(items: list[dict]) -> list[dict]:\n        \"\"\"Convert a list of Responses API items into chat messages.\n\n        Input items may be a mix of:\n            - Messages (``EasyInputMessageParam`` with ``role``, or ``type: \"message\"``).\n            - ``reasoning`` — buffered and attached as ``reasoning_content`` to the next assistant message.\n            - ``function_call`` — merged as ``tool_calls`` onto the preceding assistant message.","sourceCodeStart":480,"sourceCodeEnd":516,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/cli/serving/response.py#L480-L516","documentation":"In the Responses-style API path, ResponseHandler reads body['input'] and accepts exactly two shapes: a plain string (treated as a single user message) or a list (either flat content items, or OpenAI Responses-style dicts with a 'role'). Any other JSON type — number, object, boolean, null — triggers HTTP 422 \"'input' must be a string or list\".","triggerScenarios":"POSTing {\"input\": 123} or {\"input\": {\"text\": \"hi\"}}; sending null when no input; a client SDK serializing the field to a non-array/object primitive; malformed JSON that decodes 'input' to a scalar.","commonSituations":"Migrating from OpenAI Responses API with an object-form input; missing the input field so a default scalar is injected; hand-rolled curl payloads with wrong types.","solutions":["Send input as a string: {\"input\": \"Hello\"}","Or as a list: {\"input\": [{\"type\": \"input_text\", \"text\": \"Hello\"}]} or a list of role dicts","Wrap object payloads into a single-item content list before sending"],"exampleFix":"# before\ncurl -X POST .../responses -d '{\"model\": \"gpt2\", \"input\": {\"text\": \"hi\"}}'  # 422\n\n# after\ncurl -X POST .../responses -d '{\"model\": \"gpt2\", \"input\": \"hi\"}'","handlingStrategy":"type-guard","validationCode":"inp = body.get(\"input\")\nif not isinstance(inp, (str, list)):\n    return JSONResponse(status_code=422, content={\"error\": \"'input' must be a string or list\"})","typeGuard":"def is_valid_input(inp) -> bool:\n    return isinstance(inp, (str, list))","tryCatchPattern":"resp = await client.post(url, json=body)\nif resp.status_code == 422 and \"must be a string or list\" in resp.text:\n    body[\"input\"] = str(body[\"input\"])\n    resp = await client.post(url, json=body)","preventionTips":["Serialize input as str or list at the client","Never send objects/null in the input field","Use the official OpenAI client types to catch shape errors before shipping"],"tags":["serving","api","responses","validation","http-422"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}