pandas-dev/pandas · error · TypeError

Left and right arrays must have matching signedness. Got {le

Error message

Left and right arrays must have matching signedness. Got {left_dtype} and {right_dtype}.

What it means

Raised as a TypeError after dtype coercion when both bounds are integer-kind but one is signed and the other unsigned (e.g., int64 vs uint64). Mixing signedness would silently corrupt comparisons, so pandas refuses. Fires at pandas/core/arrays/interval.py:379.

Source

Thrown at pandas/core/arrays/interval.py:379

            lbase = getattr(left, "_ndarray", left)
            lbase = getattr(lbase, "_data", lbase).base
            rbase = getattr(right, "_ndarray", right)
            rbase = getattr(rbase, "_data", rbase).base
            if lbase is not None and lbase is rbase:
                # If these share data, then setitem could corrupt our IA
                right = right.copy()

        dtype = IntervalDtype(left.dtype, closed=closed)

        # Check for mismatched signed/unsigned integer dtypes after casting
        left_dtype = left.dtype
        right_dtype = right.dtype
        if (
            left_dtype.kind in "iu"
            and right_dtype.kind in "iu"
            and left_dtype.kind != right_dtype.kind
        ):
            raise TypeError(
                f"Left and right arrays must have matching signedness. "
                f"Got {left_dtype} and {right_dtype}."
            )
        return left, right, dtype

    @classmethod
    def _from_sequence(
        cls,
        scalars,
        *,
        dtype: Dtype | None = None,
        copy: bool = False,
    ) -> Self:
        return cls(scalars, dtype=dtype, copy=copy)

    @classmethod
    def _from_factorized(cls, values: np.ndarray, original: IntervalArray) -> Self:
        return cls._from_sequence(values, dtype=original.dtype)

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Cast both bounds to the same signed int dtype: `left.astype('int64')`, `right.astype('int64')`.
  2. If values fit in unsigned range, cast both to uint64: `left.astype('uint64')`.
  3. Promote to float64 if you cannot guarantee int range: `left.astype('float64')`.

Example fix

// before
pd.IntervalIndex.from_arrays(left_i64, right_u64)
// after
pd.IntervalIndex.from_arrays(left_i64, right_u64.astype('int64'))
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def unify_signedness(left, right, target='int64'):
    left = np.asarray(left).astype(target)
    right = np.asarray(right).astype(target)
    return left, right

Type guard

import numpy as np

def same_signedness(left, right) -> bool:
    ld = np.asarray(left).dtype
    rd = np.asarray(right).dtype
    return not (ld.kind in 'iu' and rd.kind in 'iu' and ld.kind != rd.kind)

Try / catch

try:
    ia = pd.IntervalArray(left, right)
except TypeError as e:
    if "matching signedness" in str(e):
        ia = pd.IntervalArray(left.astype('int64'), right.astype('int64'))
    else:
        raise

Prevention

When it happens

Trigger: `pd.IntervalIndex.from_arrays(np.array([1,2], dtype='int64'), np.array([3,4], dtype='uint64'))`, or merging columns whose numpy dtypes came from different sources (e.g., Arrow vs numpy).

Common situations: Combining data from pyarrow (often uint) with numpy (often int); indexing/groupby code paths that upcast lengths to uint.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/1eabd87d61130afc. Report an issue: GitHub.