openai/openai-python · error · ValueError
invalid datetime format
Error message
invalid datetime format
What it means
parse_datetime implements the SDK's ISO-8601 datetime parsing. After asserting the value is a str (not a number) it matches against a strict datetime regex; a mismatch means the string is not a recognizable ISO-8601 datetime (e.g. missing timezone where required, wrong separators, or epoch-style strings). The ValueError signals malformed datetime input, typically when server responses change shape or when local code feeds non-ISO strings into SDK model construction.
Source
Thrown at src/openai/_utils/_datetime_parse.py:93
Raise ValueError if the input is well formatted but not a valid datetime.
Raise ValueError if the input isn't well formatted.
"""
if isinstance(value, datetime):
return value
number = _get_numeric(value, "datetime")
if number is not None:
return _from_unix_seconds(number)
if isinstance(value, bytes):
value = value.decode()
assert not isinstance(value, (float, int))
match = datetime_re.match(value)
if match is None:
raise ValueError("invalid datetime format")
kw = match.groupdict()
if kw["microsecond"]:
kw["microsecond"] = kw["microsecond"].ljust(6, "0")
tzinfo = _parse_timezone(kw.pop("tzinfo"))
kw_: Dict[str, Union[None, int, timezone]] = {k: int(v) for k, v in kw.items() if v is not None}
kw_["tzinfo"] = tzinfo
return datetime(**kw_) # type: ignore
def parse_date(value: Union[date, StrBytesIntFloat]) -> date:
"""
Parse a date/int/float/string and return a datetime.date.
Raise ValueError if the input is well formatted but not a valid date.
Raise ValueError if the input isn't well formatted.View on GitHub (pinned to 9917c6e28e)
Solutions
- Normalize the input to ISO-8601 (datetime.isoformat()) before constructing the model
- If the value is epoch seconds, pass it as int/float so the unix-seconds path is used instead of regex parsing
- If the string is date-only, use the date-typed field/parse_date instead of datetime
- Validate incoming strings with datetime.fromisoformat or a regex before assignment
Example fix
# before m = MyModel(created_at="Jan 5 2024 10:00") # after from datetime import datetime m = MyModel(created_at=datetime(2024,1,5,10,0).isoformat())
Defensive patterns
Strategy: validation
Validate before calling
from datetime import datetime
try:
datetime.fromisoformat(value.replace("Z", "+00:00"))
except ValueError:
raise ValueError(f"not ISO-8601: {value!r}") Type guard
import re
ISO_DT_RE = re.compile(r"^\d{4}-\d{2}-\d{2}([T ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?)?$")
def is_iso_datetime(v: str) -> bool: return bool(ISO_DT_RE.match(v)) Try / catch
try:
parse_datetime(s)
except ValueError:
s = datetime.fromtimestamp(int(s)).isoformat() if s.isdigit() else fallback(s) Prevention
- Always emit datetime.isoformat() from producers
- Document expected timestamp format in API contracts
- Validate at ingestion before model construction
When it happens
Trigger: A response/model field typed as datetime receives a string like '2024/01/01', 'Jan 1 2024', an epoch-seconds string ('1700000000'), or any string not matching the ISO-8601 regex (date + optional time + timezone component).
Common situations: API returns a new or non-standard timestamp format after a version change; constructing models from your own JSON with locale-formatted dates; tests with hand-written date strings; mixing datetime with fields documented as date-only.
Related errors
- invalid date format
- Pagination is only supported with mappings
- The `default_headers` and `set_default_headers` arguments ar
- The `default_query` and `set_default_query` arguments are mu
- invalid type; expected {native_expected_type}, string, bytes
AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28).
Data as JSON: /api/errors/d4653104bf3f6d18.
Report an issue: GitHub.