pandas-dev/pandas · error · ValueError

must not have differing left

Error message

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

What it means

Raised when the Python `type(left)` differs from `type(right)` after dtype coercion (e.g. left is a Series and right is an Index, or left is a plain Index and right is a DatetimeIndex). IntervalArray requires both sides to be the same concrete index subclass so its internals stay symmetric.

Solutions

  1. Wrap both sides in the same container: `pd.Index(left)` and `pd.Index(right)`.
  2. Extract values uniformly with `np.asarray` if you want raw arrays, then pass to from_arrays.
  3. Normalise datetimelike sides with `ensure_wrapped_if_datetimelike` semantics — convert both to DatetimeIndex when dealing with timestamps.

Example fix

# before
IntervalArray.from_arrays(pd.Series([0,1]), pd.Index([1,2]))

# after
IntervalArray.from_arrays(pd.Index([0,1]), pd.Index([1,2]))
Defensive patterns

Strategy: validation

Validate before calling

import pandas as pd

def normalise_bounds(left, right):
    if type(left) != type(right):
        left = pd.Index(left)
        right = pd.Index(right)
    return left, right

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: `IntervalArray.from_arrays(pd.Series([0,1]), pd.Index([1,2]))`; mixing a DatetimeIndex with a plain Index of timestamps; passing a numpy array on one side and an Index on the other in a way that survives the earlier coercion.

Common situations: Constructing intervals from heterogeneous sources (DataFrame column vs Index, db result vs list); refactors that changed one side's container type; unit tests building left/right with different helpers.

Related errors


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

Appendix: 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 3b7651241d)