openai/openai-python · error · TypeError
Expected query input to be a dictionary for multipart reques
Error message
Expected query input to be a dictionary for multipart requests but got {type(json_data)} instead. What it means
The OpenAI Python SDK raises this ValueError when await client.vector_stores.file_batches.retrieve() (async) is called with a falsy batch_id. The guard fires before the request, requiring the 'vsfb_...' batch identifier to be a non-empty string for the retrieval path.
Source
Thrown at src/openai/_base_client.py:560
content_type = headers.get("Content-Type")
files = options.files
# If the given Content-Type header is multipart/form-data then it
# has to be removed so that httpx can generate the header with
# additional information for us as it has to be in this form
# for the server to be able to correctly parse the request:
# multipart/form-data; boundary=---abc--
if content_type is not None and content_type.startswith("multipart/form-data"):
if "boundary" not in content_type:
# only remove the header if the boundary hasn't been explicitly set
# as the caller doesn't want httpx to come up with their own boundary
headers.pop("Content-Type")
# As we are now sending multipart/form-data instead of application/json
# we need to tell httpx to use it, https://www.python-httpx.org/advanced/clients/#multipart-file-encoding
if json_data:
if not is_dict(json_data):
raise TypeError(
f"Expected query input to be a dictionary for multipart requests but got {type(json_data)} instead."
)
kwargs["data"] = self._serialize_multipartform(json_data)
# httpx determines whether or not to send a "multipart/form-data"
# request based on the truthiness of the "files" argument.
# This gets around that issue by generating a dict value that
# evaluates to true.
#
# https://github.com/encode/httpx/discussions/2399#discussioncomment-3814186
if not files:
files = cast(HttpxRequestFiles, ForceMultipartDict())
prepared_url = self._prepare_url(options.url)
# preserve hard-coded query params from the url
if params and prepared_url.query:
params = {**dict(prepared_url.params.items()), **params}
prepared_url = prepared_url.copy_with(raw_path=prepared_url.raw_path.split(b"?", 1)[0])View on GitHub (pinned to 9917c6e28e)
Solutions
- Capture the batch from creation and pass batch.id: batch = await client.vector_stores.file_batches.create(...); await ...retrieve(vector_store_id=vs, batch_id=batch.id).
- Persist batch IDs durably if your process may restart between creating and retrieving.
- Double-check attribute names on response objects (id, not batch_id or file_batch_id).
Example fix
# before batch = await client.vector_stores.file_batches.retrieve(vector_store_id=vs, batch_id="") # after created = await client.vector_stores.file_batches.create(vector_store_id=vs, file_ids=[f.id]) batch = await client.vector_stores.file_batches.retrieve(vector_store_id=vs, batch_id=created.id)
Defensive patterns
Strategy: validation
Validate before calling
bid = job.get("batch_id")
if not bid:
raise ValueError("job record is missing batch_id")
batch = await client.vector_stores.file_batches.retrieve(vector_store_id=vs, batch_id=bid) Type guard
def is_valid_batch_id(v: object) -> bool:
return isinstance(v, str) and v.startswith("vsfb_") and len(v) > 5 Prevention
- Persist batch IDs across process restarts.
- Verify response attribute names (.id) rather than guessing.
When it happens
Trigger: Awaiting retrieve(vector_store_id='vs_...', batch_id='') or batch_id=None, such as when the batch creation response was discarded or its ID attribute was misread.
Common situations: Forgetting to store the create() result, accessing a nonexistent attribute on the response object (silently producing None), or state that lost the batch reference between runs.
Related errors
- max_retries cannot be None. If you want to disable retries,
- Unexpected JSON data type, {type(json_data)}, cannot merge w
- Passing both `content` and `json_data` is not supported
- Pagination is only supported with mappings
- No next page expected; please check `.has_next_page()` befor
AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28).
Data as JSON: /api/errors/1b8fa400794e8a5c.
Report an issue: GitHub.