openai/openai-python · error · TypeError
Value is not iterable
Error message
Value is not iterable
What it means
During deserialization, a field typed as list[T] received a value that is neither a list nor iterable (e.g. an int, float, or None). The compat validator attempts list(value) and wraps the resulting TypeError as a clear 'Value is not iterable' error chained to the original.
Source
Thrown at src/openai/_models.py:476
list_of_items_schema,
serialization=core_schema.plain_serializer_function_ser_schema(
cls._serialize,
info_arg=False,
),
)
@staticmethod
def _validate(v: Iterable[_T], handler: "ValidatorFunctionWrapHandler") -> Any:
original_type: type[Any] = type(v)
# Normalize to list so list_schema can validate each item
if isinstance(v, list):
items: list[_T] = v
else:
try:
items = list(v)
except TypeError as e:
raise TypeError("Value is not iterable") from e
# Validate items against the inner schema
validated: list[_T] = handler(items)
# Reconstruct original container type
if original_type is list:
return validated
# str(list) produces the list's repr, not a string built from items,
# so skip reconstruction for str and its subclasses.
if issubclass(original_type, str):
return validated
try:
return original_type(validated)
except (TypeError, ValueError):
# If the type cannot be reconstructed, just return the validated list
return validated
@staticmethodView on GitHub (pinned to 9917c6e28e)
Solutions
- Inspect the raw response body for the failing field (e.g. via cast_to=dict or with_raw_response) to see the actual shape
- Fix the fixture or adjust the model type to match the real API contract
- If the shape legitimately varies, type the field as list[T] | Something and normalize after parsing
Example fix
# before
# fixture: {"data": 42}
resp = client.beta.items.list() # schema expects data: list[Item]
# after
# fixture: {"data": [{"id": "1"}]}
resp = client.beta.items.list()
Defensive patterns
Strategy: validation
Validate before calling
def ensure_list(v):
if v is None:
return []
if isinstance(v, list):
return v
return [v] # or raise, depending on contract
payload = json.loads(raw)
payload['data'] = ensure_list(payload.get('data'))
obj = MyModel.construct(**payload) Type guard
def is_iterable_list_value(v: object) -> bool:
return isinstance(v, (list, tuple)) or (hasattr(v, '__iter__') and not isinstance(v, (str, bytes, dict))) Try / catch
try:
obj = MyModel.model_validate(raw)
except TypeError as e:
if 'not iterable' in str(e):
raw = dict(raw)
raw['data'] = list(raw.get('data') or [])
obj = MyModel.model_validate(raw)
else:
raise Prevention
- Validate list-typed fields with jsonschema or a pre-check before model_validate
- Keep test fixtures shape-accurate to the documented API schema
- Pin SDK and API versions together to catch schema drift in CI
When it happens
Trigger: An API response contains a non-array value where the model schema declares a list — e.g. {"data": 42} parsed into a model with data: list[Item]; also passing a generator-exhausted object or a non-iterable sentinel when constructing models directly.
Common situations: API/schema drift where an endpoint starts returning a scalar or object instead of an array; mock/test fixtures that use the wrong JSON shape; upstream services wrapping lists in pagination objects.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Expected {json_schema} to be a dictionary; path={path}
- Pagination is only supported with mappings
- No next page expected; please check `.has_next_page()` befor
- max_retries cannot be None. If you want to disable retries,
- Unexpected JSON data type, {type(json_data)}, cannot merge w
AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28).
Data as JSON: /api/errors/712f72c08bc378df.
Report an issue: GitHub.