pandas-dev/pandas · error · TypeError

Cannot multiply with

Error message

Cannot multiply with {type(other).__name__}

What it means

Raised in TimedeltaArray.__mul__ for a scalar operand that is not bool/int/float and where numpy (>=2.1) neither raised a TypeError nor produced a timedelta64 result. Since numpy 2.1 may dispatch to other.__rmul__ instead of erroring, pandas inspects the result dtype: if it is not timedelta-like ('m'), it raises TypeError naming the offending type.

Solutions

  1. Convert the operand to a plain int or float before multiplying.
  2. If you genuinely need custom-numeric scaling, perform the arithmetic in a numeric space (total_seconds) and reconstruct the timedelta.
  3. Pin/verify numpy < 2.1 only if you cannot change the operand type — but fixing the operand is preferred.

Example fix

# before
from decimal import Decimal
pd.to_timedelta([1, 2], unit='D') * Decimal('2')  # TypeError

# after
pd.to_timedelta([1, 2], unit='D') * float(Decimal('2'))
Defensive patterns

Strategy: type-guard

Validate before calling

import numbers
import numpy as np

def as_td_scalar_multiplier(x):
    if isinstance(x, (bool, np.bool_)):
        raise TypeError('bool not allowed')
    if isinstance(x, (numbers.Integer, numbers.Real, np.integer, np.floating)):
        return x
    return float(x)

Type guard

import numbers, numpy as np

def is_supported_td_scalar(x) -> bool:
    return isinstance(x, (numbers.Integer, numbers.Real, np.integer, np.floating)) and not isinstance(x, (bool, np.bool_))

Try / catch

try:
    result = td * other
except TypeError as e:
    if 'Cannot multiply with' in str(e):
        result = td * float(other)
    else:
        raise

Prevention

When it happens

Trigger: Multiplying a timedelta64 array by an unsupported scalar type (e.g. a string, complex, Decimal, or custom numeric) where numpy 2.1+ does not itself raise.

Common situations: Passing arbitrary objects or third-party numeric types (Decimal, sympy numbers) as timedelta multipliers; numpy version changes that altered dispatch behavior.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/e5aaa4bc89c77d5c. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/arrays/timedeltas.py:555

                    # The extreme elements bound all products, so checking them
                    #  with exact Python-int arithmetic lets the common
                    #  no-overflow case use a vectorized multiply. NaT
                    #  (int64.min) always trips the bound, falling through to
                    #  the NaT-aware cython loop.
                    low_prod = int(i8_vals.min()) * other
                    high_prod = int(i8_vals.max()) * other
                    if max(abs(low_prod), abs(high_prod)) <= lib.i8max:
                        result = (i8_vals * other).view(self._ndarray.dtype)
                        return type(self)._simple_new(result, dtype=result.dtype)
                return self._mul_int_overflowsafe(np.asarray(other, dtype="i8"))
            if lib.is_float(other):
                return self._mul_float_overflowsafe(other)
            # numpy will raise TypeError for non-numeric scalar
            result = self._ndarray * other
            if result.dtype.kind != "m":
                # numpy >= 2.1 may not raise a TypeError
                # and seems to dispatch to others.__rmul__?
                raise TypeError(f"Cannot multiply with {type(other).__name__}")
            return type(self)._simple_new(result, dtype=result.dtype)

        if not hasattr(other, "dtype"):
            # list, tuple
            other = np.array(other)

        if other.dtype.kind == "b":
            # GH#58054
            raise TypeError(
                f"Cannot multiply '{self.dtype}' by bool, explicitly cast to "
                "integers instead"
            )
        if isinstance(other.dtype, (ArrowDtype, BaseMaskedDtype)):
            # GH#58054
            return NotImplemented

        if len(other) != len(self) and not lib.is_np_dtype(other.dtype, "m"):
            # Exclude timedelta64 here so we correctly raise TypeError

View on GitHub (pinned to 3b7651241d)