python/cpython · error · TypeError
unsupported type for timedelta {name} component: {type(value
Error message
unsupported type for timedelta {name} component: {type(value).__name__} What it means
Raised by timedelta.__new__ when any of its keyword components (days, seconds, microseconds, milliseconds, minutes, hours, weeks) is not an int or float. The constructor loops over all seven names and type-checks each before normalizing; even unused components passed as wrong types (e.g. a string) fail.
Source
Thrown at Lib/_pydatetime.py:667
# Doing this efficiently and accurately in C is going to be difficult
# and error-prone, due to ubiquitous overflow possibilities, and that
# C double doesn't have enough bits of precision to represent
# microseconds over 10K years faithfully. The code here tries to make
# explicit where go-fast assumptions can be relied on, in order to
# guide the C implementation; it's way more convoluted than speed-
# ignoring auto-overflow-to-long idiomatic Python could be.
for name, value in (
("days", days),
("seconds", seconds),
("microseconds", microseconds),
("milliseconds", milliseconds),
("minutes", minutes),
("hours", hours),
("weeks", weeks)
):
if not isinstance(value, (int, float)):
raise TypeError(
f"unsupported type for timedelta {name} component: {type(value).__name__}"
)
# Final values, all integer.
# s and us fit in 32-bit signed ints; d isn't bounded.
d = s = us = 0
# Normalize everything to days, seconds, microseconds.
days += weeks*7
seconds += minutes*60 + hours*3600
microseconds += milliseconds*1000
# Get rid of all fractions, and normalize s and us.
# Take a deep breath <wink>.
if isinstance(days, float):
dayfrac, days = _math.modf(days)
daysecondsfrac, daysecondswhole = _math.modf(dayfrac * (24.*3600.))
assert daysecondswhole == int(daysecondswhole) # can't overflowView on GitHub (pinned to bc6749cc3b)
Solutions
- Convert numeric strings first: timedelta(minutes=int(cfg['timeout']))
- Guard optional values: timedelta(minutes=cfg['timeout'] or 0)
- Convert Decimal to float or int (mind precision) before passing
Example fix
// before wait = timedelta(seconds=config['retry_after']) # '30' from JSON // after wait = timedelta(seconds=float(config['retry_after']))
Defensive patterns
Strategy: validation
Validate before calling
parts = {k: float(v) for k, v in cfg.items()}
wait = timedelta(**parts) Type guard
def valid_td_component(v) -> bool:
return isinstance(v, (int, float)) and not isinstance(v, bool) or isinstance(v, bool) Prevention
- Convert config/env/JSON strings to int/float before timedelta()
- Guard optional values: cfg.get('minutes') or 0
- Convert Decimal explicitly (float(d) or int(d))
When it happens
Trigger: timedelta(days='7'); timedelta(minutes=None); timedelta(seconds=Decimal('30')) — Decimal is not int/float and fails; calling timedelta(**json_config) with string values from config.
Common situations: Values coming from JSON/YAML/env vars as strings; None defaults leaking from optional config (timedelta(minutes=cfg.get('timeout'))); Decimal monetary values passed unconverted.
Related errors
- tzinfo.tzname() must return None or string, not {type(name).
- tzinfo.{name}() must return None or timedelta, not {type(off
- tzinfo argument must be None or of a tzinfo subclass, not {t
- timedelta # of days is too large: %d
- 'NoneType' object cannot be interpreted as an integer
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/ef89b16ff715e490.
Report an issue: GitHub.