python/cpython · error · TypeError
strptime() argument {} must be str, not {}
Error message
strptime() argument {} must be str, not {} What it means
_strptime type-checks both of its arguments up front: for index, arg in enumerate([data_string, format]) it requires str. This TypeError is raised when the data string (index 0) or the format (index 1) is not a str — e.g. bytes, int, None. The message reports the argument position and the offending type.
Source
Thrown at Lib/_strptime.py:543
# the same as that specified by %U or %W).
week_0_length = (7 - first_weekday) % 7
if week_of_year == 0:
return 1 + day_of_week - first_weekday
else:
days_to_week = week_0_length + (7 * (week_of_year - 1))
return 1 + days_to_week + day_of_week
def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
"""Return a 3-tuple consisting of a tuple with time components,
an int containing the number of microseconds, and an int
containing the microseconds part of the GMT offset, based on the
input string and the format string."""
for index, arg in enumerate([data_string, format]):
if not isinstance(arg, str):
msg = "strptime() argument {} must be str, not {}"
raise TypeError(msg.format(index, type(arg)))
global _TimeRE_cache, _regex_cache
with _cache_lock:
locale_time = _TimeRE_cache.locale_time
if (_getlang() != locale_time.lang or
time.tzname != locale_time.tzname or
time.daylight != locale_time.daylight):
_TimeRE_cache = TimeRE()
_regex_cache.clear()
locale_time = _TimeRE_cache.locale_time
if len(_regex_cache) > _CACHE_MAX_SIZE:
_regex_cache.clear()
format_regex = _regex_cache.get(format)
if not format_regex:
try:
format_regex = _TimeRE_cache.compile(format)
# KeyError raised when a bad format is found; can be specified as
# \\, in which case it was a stray % but with a space after itView on GitHub (pinned to bc6749cc3b)
Solutions
- Decode bytes to str before parsing: time.strptime(data.decode('utf-8'), fmt)
- If you have a timestamp number, use datetime.fromtimestamp(ts) instead of strptime
- If you have a date/datetime object, call .strftime(fmt) — strptime is only for strings
Example fix
# before >>> datetime.strptime(b'2020-01-01', '%Y-%m-%d') TypeError: strptime() argument 0 must be str, not <class 'bytes'> # after >>> datetime.strptime(b'2020-01-01'.decode(), '%Y-%m-%d') datetime.datetime(2020, 1, 1, 0, 0)
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(data_string, str):
data_string = data_string.decode('utf-8') if isinstance(data_string, bytes) else str(data_string)
if not isinstance(fmt, str):
raise TypeError('fmt must be str') Type guard
def is_strptime_args(*args) -> bool:
return all(isinstance(a, str) for a in args) Try / catch
try:
dt = datetime.strptime(s, fmt)
except TypeError:
dt = datetime.strptime(s.decode() if isinstance(s, bytes) else str(s), fmt) Prevention
- Open data files in text mode ('r') not binary ('rb') when the contents feed strptime
- Use datetime.fromtimestamp() for numeric timestamps instead of strptime
- Annotate parser entry points as (s: str, fmt: str) and run mypy
When it happens
Trigger: Calling time.strptime() or datetime.datetime.strptime() with bytes (b'2020-01-01'), an int/float timestamp, None, or a non-str format argument.
Common situations: Reading data from files/network opened in binary mode and passing bytes directly; passing a datetime.date object instead of its string form; forgetting that strptime (parse) is the inverse of strftime (format).
Related errors
- must be str, not %s
- fromisoformat: argument must be str
- timezone changed during initialization
- Day of month directive '%d' may not be used without a year d
- stray %% in format '%s'
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/b938826652b1bccc.
Report an issue: GitHub.