python/cpython · error · ValueError
Invalid isoformat string: {time_string!r}
Error message
Invalid isoformat string: {time_string!r} What it means
Raised by time.fromisoformat() when _parse_isoformat_time cannot parse the string as an ISO 8601 time. The original lower-level ValueError is suppressed (`from None`) and replaced with this message echoing the offending string, so the repr of the bad input is visible in the traceback. Common causes are stray characters, wrong separators, or invalid component values.
Source
Thrown at Lib/_pydatetime.py:1650
__str__ = isoformat
@classmethod
def fromisoformat(cls, time_string):
"""Construct a time from a string in one of the ISO 8601 formats."""
if not isinstance(time_string, str):
raise TypeError('fromisoformat: argument must be str')
# The spec actually requires that time-only ISO 8601 strings start with
# T, but the extended format allows this to be omitted as long as there
# is no ambiguity with date strings.
time_string = time_string.removeprefix('T')
try:
time_components, _, error_from_components, error_from_tz = (
_parse_isoformat_time(time_string)
)
except ValueError:
raise ValueError(
f'Invalid isoformat string: {time_string!r}') from None
else:
if error_from_tz:
raise error_from_tz
if error_from_components:
raise ValueError(
"Minute, second, and microsecond must be 0 when hour is 24"
)
return cls(*time_components)
def strftime(self, format):
"""Format using strftime(). The date part of the timestamp passed
to underlying strftime should not be used.
For a list of supported format codes, see the documentation:
https://docs.python.org/3/library/datetime.html#format-codes
"""View on GitHub (pinned to bc6749cc3b)
Solutions
- Normalize the input before parsing: strip whitespace, convert 12-hour AM/PM to 24-hour, replace '.' time separators with ':'
- Use dateutil.parser.parse or a targeted strptime format for non-ISO inputs: datetime.strptime(s, '%I:%M %p').time()
- For free-form fields, validate with a regex (e.g. ^\d{2}:\d{2}(:\d{2}(\.\d+)?)?$) before calling fromisoformat
Example fix
# before
t = time.fromisoformat('1:30 PM')
# after
from datetime import datetime
t = datetime.strptime('1:30 PM', '%I:%M %p').time() Defensive patterns
Strategy: validation
Validate before calling
import re
ISO_TIME = re.compile(r'^\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?(Z|[+-]\d{2}:?\d{2})?$')
s = s.strip()
if not ISO_TIME.match(s):
raise ValueError(f'not an ISO time: {s!r}')
t = time.fromisoformat(s) Type guard
def looks_like_iso_time(s: str) -> bool:
return bool(re.match(r'^\d{2}:\d{2}(:\d{2}(\.\d{1,6})?)?$', s)) Try / catch
try:
t = time.fromisoformat(s)
except ValueError:
t = datetime.strptime(s.strip(), '%I:%M %p').time() # known fallback format Prevention
- Strip whitespace and normalize separators before parsing
- Constrain user input with a regex or input mask at the form layer
- Route non-ISO formats (AM/PM, locale variants) to strptime or dateutil explicitly
When it happens
Trigger: time.fromisoformat('12.30.00') (dots instead of colons); time.fromisoformat('25:00') (hour out of range); time.fromisoformat('12:30:00 UTC') (trailing junk); time.fromisoformat('2024-01-01') (a date, not a time); time.fromisoformat('') (empty string).
Common situations: User-supplied 'HH:MM' input forms (these are valid), but variants like '12 noon', 'h12:30', or locale-formatted times are not; concatenating date and time without the separator; whitespace not stripped; CSV/Excel exports with non-ISO times like '1:30 PM'.
Related errors
- Minute, second, and microsecond must be 0 when hour is 24
- Invalid ISO string
- Invalid isoformat string
- Inconsistent use of dash separator
- Incomplete time component
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/5c147b40f8e71a62.
Report an issue: GitHub.