{"record":{"id":"712f72c08bc378df","repo":"openai/openai-python","slug":"value-is-not-iterable","errorCode":null,"errorMessage":"Value is not iterable","messagePattern":"Value is not iterable","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/openai/_models.py","lineNumber":476,"sourceCode":"            list_of_items_schema,\n            serialization=core_schema.plain_serializer_function_ser_schema(\n                cls._serialize,\n                info_arg=False,\n            ),\n        )\n\n    @staticmethod\n    def _validate(v: Iterable[_T], handler: \"ValidatorFunctionWrapHandler\") -> Any:\n        original_type: type[Any] = type(v)\n\n        # Normalize to list so list_schema can validate each item\n        if isinstance(v, list):\n            items: list[_T] = v\n        else:\n            try:\n                items = list(v)\n            except TypeError as e:\n                raise TypeError(\"Value is not iterable\") from e\n\n        # Validate items against the inner schema\n        validated: list[_T] = handler(items)\n\n        # Reconstruct original container type\n        if original_type is list:\n            return validated\n        # str(list) produces the list's repr, not a string built from items,\n        # so skip reconstruction for str and its subclasses.\n        if issubclass(original_type, str):\n            return validated\n        try:\n            return original_type(validated)\n        except (TypeError, ValueError):\n            # If the type cannot be reconstructed, just return the validated list\n            return validated\n\n    @staticmethod","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/openai/openai-python/blob/9917c6e28e66e90e1227b3d223c06a8c5441515a/src/openai/_models.py#L458-L494","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\n# fixture: {\"data\": 42}\nresp = client.beta.items.list()  # schema expects data: list[Item]\n# after\n# fixture: {\"data\": [{\"id\": \"1\"}]}\nresp = client.beta.items.list()\n","handlingStrategy":"validation","validationCode":"def ensure_list(v):\n    if v is None:\n        return []\n    if isinstance(v, list):\n        return v\n    return [v]  # or raise, depending on contract\n\npayload = json.loads(raw)\npayload['data'] = ensure_list(payload.get('data'))\nobj = MyModel.construct(**payload)","typeGuard":"def is_iterable_list_value(v: object) -> bool:\n    return isinstance(v, (list, tuple)) or (hasattr(v, '__iter__') and not isinstance(v, (str, bytes, dict)))","tryCatchPattern":"try:\n    obj = MyModel.model_validate(raw)\nexcept TypeError as e:\n    if 'not iterable' in str(e):\n        raw = dict(raw)\n        raw['data'] = list(raw.get('data') or [])\n        obj = MyModel.model_validate(raw)\n    else:\n        raise","preventionTips":["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"],"tags":["pydantic","deserialization","schema-mismatch","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"9917c6e28e66e90e1227b3d223c06a8c5441515a","analyzedAt":"2026-08-28T11:46:34.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}