pandas-dev/pandas · error · TypeError
dtype must be an IntervalDtype, got
Error message
dtype must be an IntervalDtype, got {dtype} What it means
Raised in `IntervalArray._ensure_simple_new_inputs` when an explicit `dtype` is given but, after `pandas_dtype(dtype)`, it is not an `IntervalDtype`. To override the inferred subtype you must pass a dtype that resolves to IntervalDtype (e.g. `'interval[int64]'`, `IntervalDtype('int64')`); a plain `'int64'` is the underlying subtype, not the array dtype.
Solutions
- Wrap the subtype in IntervalDtype: `dtype='interval[int64]'` or `dtype=IntervalDtype(np.int64)`.
- Omit dtype entirely and let pandas infer the subtype from left/right.
- If you only need to coerce the subtype, cast left/right beforehand with `.astype(np.int64)` and pass dtype=None.
Example fix
# before pd.arrays.IntervalArray.from_arrays([0,1],[1,2], dtype='int64') # after pd.arrays.IntervalArray.from_arrays([0,1],[1,2], dtype='interval[int64]') # or omit dtype pd.arrays.IntervalArray.from_arrays([0,1],[1,2])
Defensive patterns
Strategy: validation
Validate before calling
import pandas as pd
from pandas import IntervalDtype
def interval_dtype_or_none(dtype):
if dtype is None:
return None
d = pd.api.types.pandas_dtype(dtype)
if not isinstance(d, IntervalDtype):
# wrap the subtype
return IntervalDtype(dtype)
return d Type guard
from pandas import IntervalDtype
import pandas as pd
def is_interval_dtype_spec(dtype) -> bool:
if dtype is None:
return True
try:
return isinstance(pd.api.types.pandas_dtype(dtype), IntervalDtype)
except TypeError:
return False Try / catch
try:
arr = pd.arrays.IntervalArray.from_arrays(l, r, dtype=dtype)
except TypeError as e:
if 'dtype must be an IntervalDtype' in str(e):
arr = pd.arrays.IntervalArray.from_arrays(l, r, dtype=f'interval[{dtype}]')
else:
raise Prevention
- Use 'interval[subtype]' strings rather than bare subtype strings.
- Omit dtype when in doubt and let pandas infer.
- Build dtype via IntervalDtype(subtype) in library code.
When it happens
Trigger: Calling `IntervalArray.from_arrays(left, right, dtype='int64')` expecting it to set the subtype; passing `dtype=np.float64` or `dtype='float'` directly instead of `'interval[float64]'`; using a string that pandas_dtype resolves to a non-Interval dtype.
Common situations: Users familiar with numeric Index dtypes assuming the same string works for intervals; constructing from read_csv dtypes; copy-pasting subtype dtype where the wrapper dtype is required.
Related errors
- category, object, and string subtypes are not supported for…
- (...) must be called with a collection of some kind, was…
- ExtensionArray.fillna does not support filling with a dict…
- invalid dtype
- Left and right arrays must have matching signedness. Got
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/32d9f5ed4ebd86ec.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/interval.py:304
left = ensure_index(left, copy=copy)
right = ensure_index(right, copy=copy)
if closed is None and isinstance(dtype, IntervalDtype):
closed = dtype.closed
closed = closed or "right"
if dtype is not None:
# GH 19262: dtype must be an IntervalDtype to override inferred
dtype = pandas_dtype(dtype)
if isinstance(dtype, IntervalDtype):
if dtype.subtype is not None:
left = left.astype(dtype.subtype)
right = right.astype(dtype.subtype)
else:
msg = f"dtype must be an IntervalDtype, got {dtype}"
raise TypeError(msg)
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"
)View on GitHub (pinned to 3b7651241d)