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

  1. Normalize the input to ISO-8601 (datetime.isoformat()) before constructing the model
  2. If the value is epoch seconds, pass it as int/float so the unix-seconds path is used instead of regex parsing
  3. If the string is date-only, use the date-typed field/parse_date instead of datetime
  4. 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

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


AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28). Data as JSON: /api/errors/d4653104bf3f6d18. Report an issue: GitHub.