openai/openai-python · error · TypeError
invalid type; expected {native_expected_type}, string, bytes
Error message
invalid type; expected {native_expected_type}, string, bytes, int or float What it means
The SDK's datetime/date coercion helper accepts str, bytes, int, or float and calls float(value) to convert. When the value's type is neither convertible (TypeError from float(), e.g. None, list, dict, or an arbitrary object) the helper raises this TypeError to signal that the input type is fundamentally unconvertible. It is raised from within parse_datetime/parse_date when coercing a raw value, usually because the caller passed a None or a non-scalar where a datetime-like value was expected.
Source
Thrown at src/openai/_utils/_datetime_parse.py:41
EPOCH = datetime(1970, 1, 1)
# if greater than this, the number is in ms, if less than or equal it's in seconds
# (in seconds this is 11th October 2603, in ms it's 20th August 1970)
MS_WATERSHED = int(2e10)
# slightly more than datetime.max in ns - (datetime.max - EPOCH).total_seconds() * 1e9
MAX_NUMBER = int(3e20)
def _get_numeric(value: StrBytesIntFloat, native_expected_type: str) -> Union[None, int, float]:
if isinstance(value, (int, float)):
return value
try:
return float(value)
except ValueError:
return None
except TypeError:
raise TypeError(f"invalid type; expected {native_expected_type}, string, bytes, int or float") from None
def _from_unix_seconds(seconds: Union[int, float]) -> datetime:
if seconds > MAX_NUMBER:
return datetime.max
elif seconds < -MAX_NUMBER:
return datetime.min
while abs(seconds) > MS_WATERSHED:
seconds /= 1000
dt = EPOCH + timedelta(seconds=seconds)
return dt.replace(tzinfo=timezone.utc)
def _parse_timezone(value: Optional[str]) -> Union[None, int, timezone]:
if value == "Z":
return timezone.utc
elif value is not None:View on GitHub (pinned to 9917c6e28e)
Solutions
- Ensure the field is a str/bytes/int/float (e.g. an ISO-8601 string or unix seconds) before assignment
- Fix the upstream data so the timestamp field is never None or a container
- If the value may be absent, use a conditional/exclude the field rather than passing None
- Catch TypeError at the boundary that produces the raw data and log which field is malformed
Example fix
# before obj = SomeModel(created=None) # after obj = SomeModel(created=int(time.time())) # or omit the field if the model allows
Defensive patterns
Strategy: validation
Validate before calling
if not isinstance(value, (str, bytes, int, float)):
raise ValueError(f"bad timestamp: {value!r}") Type guard
def is_coercible_ts(v: object) -> bool:
return isinstance(v, (str, bytes, int, float)) and not isinstance(v, bool) Try / catch
try:
parse_datetime(raw)
except TypeError as e:
raise ValueError(f"field X must be str/int/float, got {type(raw)}") from e Prevention
- Normalize timestamps at your data boundary
- Never pass None for datetime-typed fields
- Use .isoformat() on datetime objects before assignment
When it happens
Trigger: Passing None, a dict, list, datetime object already parsed, or any non-string/number object to a field the SDK model coerces into a datetime or date (e.g. constructing model objects locally from raw dicts, or datetime parsing of untyped payloads via parse_datetime/parse_date).
Common situations: Building request/response models manually from JSON where a timestamp field is null; copying pydantic-v1 style code that passed datetime fields as dicts; upgrading code that previously silently passed through bad values before coercion was added.
Related errors
- Invalid `http_client` argument; Expected an instance of `htt
- 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/c8ebe5a647e05867.
Report an issue: GitHub.