python/cpython · error · ValueError

Invalid isoformat string: {date_string!r}

Error message

Invalid isoformat string: {date_string!r}

What it means

Raised by date.fromisoformat() when the string length is not 7, 8, or 10 characters — the only shapes date.fromisoformat accepts before 3.11 (YYYY-MM-DD 10 chars, plus compact YYYYMMDD 8 and YYYY-Www 7 for ISO weeks in later versions). Any other length, including datetime strings with a 'T' time part, fails here for date.fromisoformat.

Source

Thrown at Lib/_pydatetime.py:1060

        January 1 of year 1 is day 1.  Only the year, month and day are
        non-zero in the result.
        """
        y, m, d = _ord2ymd(n)
        return cls(y, m, d)

    @classmethod
    def fromisoformat(cls, date_string):
        """Construct a date from a string in ISO 8601 format."""

        if not isinstance(date_string, str):
            raise TypeError('Argument must be a str')

        if not date_string.isascii():
            raise ValueError('Argument must be an ASCII str')

        if len(date_string) not in (7, 8, 10):
            raise ValueError(f'Invalid isoformat string: {date_string!r}')

        try:
            return cls(*_parse_isoformat_date(date_string))
        except Exception:
            raise ValueError(f'Invalid isoformat string: {date_string!r}')

    @classmethod
    def fromisocalendar(cls, year, week, day):
        """Construct a date from the ISO year, week number and weekday.

        This is the inverse of the date.isocalendar() function"""
        return cls(*_isoweek_to_gregorian(year, week, day))

    @classmethod
    def strptime(cls, date_string, format):
        """Parse string according to the given date format (like time.strptime()).

        For a list of supported format codes, see the documentation:

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Use datetime.fromisoformat() when the string contains a time component
  2. Strip whitespace: date.fromisoformat(s.strip())
  3. Slice the date part: date.fromisoformat(s[:10]) for well-formed ISO datetimes

Example fix

# before
d = date.fromisoformat('2024-01-01T00:00:00')  # 19 chars -> ValueError
# after
from datetime import datetime
d = datetime.fromisoformat('2024-01-01T00:00:00').date()
Defensive patterns

Strategy: validation

Validate before calling

s = s.strip()
if 'T' in s or ':' in s:
    raise ValueError('use datetime.fromisoformat for datetime strings')
if len(s) not in (7, 8, 10):
    raise ValueError(f'unexpected isoformat length: {len(s)}')
d = date.fromisoformat(s)

Type guard

def is_date_only_iso(s: str) -> bool:
    return isinstance(s, str) and len(s.strip()) in (7, 8, 10) and 'T' not in s

Prevention

When it happens

Trigger: date.fromisoformat('2024-01-01T00:00:00') (length 19, contains time — use datetime.fromisoformat); date.fromisoformat('2024-1-1') (length 8 but wrong shape may still fail later); trailing whitespace or newline making the length 11.

Common situations: Receiving full ISO datetimes from APIs (e.g. database DATE columns or JSON 'created_at' fields) and passing them to date.fromisoformat; untrimmed input with \n from files; ISO week strings on Python < 3.11.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/9716610354c92809. Report an issue: GitHub.