pandas-dev/pandas · error · ValueError

must not have differing left [{type(left).__name__}] and rig

Error message

must not have differing left [{type(left).__name__}] and right [{type(right).__name__}] types

What it means

Raised after IntervalArray coerces float/integer mismatches when the underlying Python types of `left` and `right` still differ (e.g., one is a pandas Index and the other a bare numpy array, or one is an ExtensionArray-backed object and the other is not). The IntervalArray requires both sides to be the same array type so it can store them symmetrically. Fires at pandas/core/arrays/interval.py:323.

Source

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

            if dtype.closed is None:
                # possibly loading an old pickle
                dtype = IntervalDtype(dtype.subtype, closed)
            elif closed != dtype.closed:
                raise ValueError("closed keyword does not match dtype.closed")

        # coerce dtypes to match if needed
        if is_float_dtype(left.dtype) and is_integer_dtype(right.dtype):
            right = right.astype(left.dtype)
        elif is_float_dtype(right.dtype) and is_integer_dtype(left.dtype):
            left = left.astype(right.dtype)

        if type(left) != type(right):
            msg = (
                f"must not have differing left [{type(left).__name__}] and "
                f"right [{type(right).__name__}] types"
            )
            raise ValueError(msg)
        if (
            isinstance(left.dtype, CategoricalDtype)
            or is_string_dtype(left.dtype)
            or is_string_dtype(right.dtype)
        ):
            # GH 19016, GH 66518: reject unsupported right-side dtypes too.
            msg = (
                "category, object, and string subtypes are not supported "
                "for IntervalArray"
            )
            raise TypeError(msg)
        if isinstance(left, ABCPeriodIndex):
            msg = "Period dtypes are not supported, use a PeriodIndex instead"
            raise ValueError(msg)
        if isinstance(left, ABCDatetimeIndex) and str(left.tz) != str(right.tz):
            msg = (
                "left and right must have the same time zone, got "
                f"'{left.tz}' and '{right.tz}'"

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Wrap both sides in the same container before passing: `pd.Index(left)` and `pd.Index(right)`.
  2. If using ArrowExtensionArray on one side, convert both via `.convert_dtypes(dtype_backend='pyarrow')` or fall back to numpy on both.
  3. Build from equal-typed numpy arrays: `np.asarray(left)`, `np.asarray(right)`.

Example fix

// before
pd.IntervalArray(df['low'].index, np.asarray(df['high']))
// after
pd.IntervalArray(pd.Index(df['low']), pd.Index(df['high']))
Defensive patterns

Strategy: validation

Validate before calling

def coerce_interval_inputs(left, right):
    import pandas as pd
    left = pd.Index(left)
    right = pd.Index(right)
    if type(left) is not type(right):
        # fall back to plain Index of common dtype
        left = pd.Index(left.to_numpy())
        right = pd.Index(right.to_numpy())
    return left, right

Type guard

def same_container_type(left, right) -> bool:
    return type(left) is type(right)

Try / catch

try:
    ia = pd.IntervalArray(left, right)
except ValueError as e:
    if "differing left" in str(e):
        ia = pd.IntervalArray(pd.Index(left), pd.Index(right))
    else:
        raise

Prevention

When it happens

Trigger: Mixing an `Index` for one side and a list/ndarray/ExtensionArray for the other when calling `pd.IntervalArray(left, right)` or `IntervalIndex.from_arrays`, or mixing an Arrow-backed array with a numpy-backed one.

Common situations: Building intervals where one side comes from a DataFrame column (Index/Series-backed) and the other is computed inline as a Python list or numpy array; mixing pyarrow-backed and numpy-backed data.

Related errors


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