{"record":{"id":"5cc82be10f25f669","repo":"openai/openai-python","slug":"multipart-request-body-must-be-a-mapping","errorCode":null,"errorMessage":"Multipart request body must be a mapping","messagePattern":"Multipart request body must be a mapping","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/openai/_multipart.py","lineNumber":20,"sourceCode":"\nfrom __future__ import annotations\n\nfrom typing import Mapping, cast\n\nfrom ._types import Body, Omit, NotGiven, FileTypes, RequestFiles\nfrom ._utils._json import openapi_dumps\n\n\ndef encode_multipart(\n    body: object,\n    extra_body: Body | None,\n    encodings: Mapping[str, tuple[str, bool]],\n    raw_body_field: str | None = None,\n    existing_files: RequestFiles | None = None,\n) -> tuple[dict[str, object] | None, RequestFiles | None, bytes | None, str]:\n    \"\"\"Prepare explicitly encoded form fields without flattening their JSON contents.\"\"\"\n    if not isinstance(body, Mapping):\n        raise TypeError(\"Multipart request body must be a mapping\")\n    if extra_body is not None and not isinstance(extra_body, Mapping):\n        raise TypeError(\"Multipart extra_body must be a mapping\")\n    original = cast(Mapping[str, object], body)\n    overrides = cast(Mapping[str, object], extra_body or {})\n    merged = {key: value for key, value in {**original, **overrides}.items() if not isinstance(value, (Omit, NotGiven))}\n    # A raw request alternative is safe only when there is no other payload to lose.\n    # Explicit null remains a JSON part; only an omitted field selects the raw body.\n    if not existing_files and raw_body_field is not None and set(merged) == {raw_body_field}:\n        value = merged[raw_body_field]\n        if not isinstance(value, str):\n            raise TypeError(\"Raw multipart alternative must be a string\")\n        return None, None, value.encode(\"utf-8\"), encodings[raw_body_field][0]\n\n    files: list[tuple[str, FileTypes]] = list(\n        existing_files.items() if isinstance(existing_files, Mapping) else (existing_files or [])\n    )\n    for name, (content_type, as_json) in encodings.items():\n        if name not in merged:","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/openai/openai-python/blob/9917c6e28e66e90e1227b3d223c06a8c5441515a/src/openai/_multipart.py#L2-L38","documentation":"encode_multipart() requires the request body to be a Mapping (dict-like) so it can merge, filter NotGiven/Omit values, and encode each field as a form part. A non-mapping body (e.g. a string, bytes, or list) cannot be processed this way, so a TypeError is raised immediately.","triggerScenarios":"Calling a multipart endpoint (file upload/transcription) via client.<resource>.create(...) with body as a string/bytes/list, or calling encode_multipart directly with a non-mapping body.","commonSituations":"Passing a pre-serialized JSON string as the body; custom wrappers that convert the body dict to another type before calling the SDK; calling internal helpers with raw payloads.","solutions":["Pass the body as a dict/Mapping of field names to values","If you have serialized JSON, parse it back to a dict before the call, or use a JSON (non-multipart) endpoint","For raw string alternatives, use the documented raw-body field mechanism rather than replacing the whole body"],"exampleFix":"// before\nclient.files.create(file=open('f.txt','rb'), purpose='assistants', body='raw')\n// after\nclient.files.create(file=open('f.txt','rb'), purpose='assistants')","handlingStrategy":"type-guard","validationCode":"from collections.abc import Mapping\nassert isinstance(body, Mapping), 'multipart body must be a dict'","typeGuard":"from collections.abc import Mapping\nfrom typing import TypeGuard\n\ndef is_multipart_body(value: object) -> TypeGuard[Mapping[str, object]]:\n    return isinstance(value, Mapping)","tryCatchPattern":null,"preventionTips":["Always pass multipart bodies as dicts of field->value","Parse serialized JSON back to a dict before sending"],"tags":["python","multipart","request-body","validation"],"backgroundTag":"invalid-request-body-type","analyzedSha":"9917c6e28e66e90e1227b3d223c06a8c5441515a","analyzedAt":"2026-08-28T11:46:34.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}