pandas-dev/pandas · error · ValueError
missing values must be missing in the same location both lef
Error message
missing values must be missing in the same location both left and right sides
What it means
Raised by `_validate` when the NA mask of `left` differs from the NA mask of `right`. An interval is either fully present or fully missing at each position; a half-NaN interval is meaningless. Fires at pandas/core/arrays/interval.py:620.
Source
Thrown at pandas/core/arrays/interval.py:620
* dtype is correct
* left and right match lengths
* left and right have the same missing values
* left is always below right
"""
if not isinstance(dtype, IntervalDtype):
msg = f"invalid dtype: {dtype}"
raise ValueError(msg)
if len(left) != len(right):
msg = "left and right must have the same length"
raise ValueError(msg)
left_mask = notna(left)
right_mask = notna(right)
if not (left_mask == right_mask).all():
msg = (
"missing values must be missing in the same "
"location both left and right sides"
)
raise ValueError(msg)
if not (left[left_mask] <= right[left_mask]).all():
msg = "left side of interval must be <= right side"
raise ValueError(msg)
def _shallow_copy(self, left, right) -> Self:
"""
Return a new IntervalArray with the replacement attributes
Parameters
----------
left : Index
Values to be used for the left-side of the intervals.
right : Index
Values to be used for the right-side of the intervals.
"""
dtype = IntervalDtype(left.dtype, closed=self.closed)
left, right, dtype = self._ensure_simple_new_inputs(left, right, dtype=dtype)
View on GitHub (pinned to 71959b8cb9)
Solutions
- Co-locate NA: `mask = left.isna() | right.isna(); left[mask] = right[mask] = np.nan`.
- Drop rows where either side is NA before constructing: `df.dropna(subset=['lo','hi'])`.
- Impute the missing bound from domain knowledge before building intervals.
Example fix
// before pd.IntervalIndex.from_arrays(df['lo'], df['hi']) # NA misaligned // after m = df['lo'].isna() | df['hi'].isna() df = df.loc[~m] pd.IntervalIndex.from_arrays(df['lo'], df['hi'])
Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
import pandas as pd
def colocate_na(left, right):
left = pd.Series(left)
right = pd.Series(right)
mask = left.isna() | right.isna()
left[mask] = np.nan
right[mask] = np.nan
return left.to_numpy(), right.to_numpy() Type guard
import pandas as pd
def na_masks_match(left, right) -> bool:
return (pd.notna(left) == pd.notna(right)).all() Try / catch
try:
ia = pd.IntervalArray(left, right)
except ValueError as e:
if "missing in the same location" in str(e):
l, r = colocate_na(left, right)
ia = pd.IntervalArray(l, r)
else:
raise Prevention
- Co-locate NA before constructing: set both sides NA where either is NA.
- Drop rows with partial NA in ETL preprocessing.
- Assert na_masks_match(left, right) in unit tests.
When it happens
Trigger: `from_arrays([1, np.nan, 3], [2, 4, np.nan])` — position 1 has NaN left but a real right value.
Common situations: Joining bound columns where one has missing timestamps and the other does not; ETL that nulls only one endpoint.
Related errors
- closed keyword does not match dtype.closed
- invalid dtype: {dtype}
- left and right must have the same length
- left side of interval must be <= right side
- No such keys(s): {pat!r}
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/54104f029e851ef2.
Report an issue: GitHub.