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 overflow

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Convert numeric strings first: timedelta(minutes=int(cfg['timeout']))
  2. Guard optional values: timedelta(minutes=cfg['timeout'] or 0)
  3. 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

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


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