pandas-dev/pandas · error · ValueError
invalid option for 'closed': {closed}
Error message
invalid option for 'closed': {closed} What it means
Raised by IntervalArray.set_closed when the 'closed' argument is not one of {'left','right','both','neither'} (the VALID_CLOSED frozenset). Closure must be a known side specification; any other string/value is rejected before constructing the new dtype.
Source
Thrown at pandas/core/arrays/interval.py:1483
--------
IntervalArray.closed : Returns inclusive side of the Interval.
arrays.IntervalArray.closed : Returns inclusive side of the IntervalArray.
Examples
--------
>>> index = pd.arrays.IntervalArray.from_breaks(range(4))
>>> index
<IntervalArray>
[(0, 1], (1, 2], (2, 3]]
Length: 3, dtype: interval[int64, right]
>>> index.set_closed("both")
<IntervalArray>
[[0, 1], [1, 2], [2, 3]]
Length: 3, dtype: interval[int64, both]
"""
if closed not in VALID_CLOSED:
msg = f"invalid option for 'closed': {closed}"
raise ValueError(msg)
left, right = self._left, self._right
dtype = IntervalDtype(left.dtype, closed=closed)
return self._simple_new(left, right, dtype=dtype)
@property
def is_non_overlapping_monotonic(self) -> bool:
"""
Return a boolean whether the IntervalArray/IntervalIndex\
is non-overlapping and monotonic.
Non-overlapping means (no Intervals share points), and monotonic means
either monotonic increasing or monotonic decreasing.
See Also
--------
overlaps : Check if two IntervalIndex objects overlap.
View on GitHub (pinned to 71959b8cb9)
Solutions
- Use one of the four literal values: 'left', 'right', 'both', or 'neither'.
- Lowercase and validate the input string before passing: closed if closed in {'left','right','both','neither'} else raise.
- Check your config source for stray quotes/whitespace and strip them.
Example fix
# before
arr = pd.arrays.IntervalArray.from_tuples([(0, 1)])
arr.set_closed('Right')
# after
arr.set_closed('right') Defensive patterns
Strategy: validation
Validate before calling
VALID = {'left', 'right', 'both', 'neither'}
def normalize_closed(s):
s = str(s).strip().lower()
if s not in VALID:
raise ValueError(f"closed must be one of {VALID}, got {s!r}")
return s Type guard
def is_valid_closed(s) -> bool:
return isinstance(s, str) and s in {'left', 'right', 'both', 'neither'} Prevention
- Lowercase and strip config-driven 'closed' values before use.
- Keep closed values in an Enum at the API boundary.
- Reject unknown closed values at parse time, not at array-construction time.
When it happens
Trigger: Calling arr.set_closed('Right') (wrong case), arr.set_closed('closed'), arr.set_closed(None), or arr.set_closed('outside').
Common situations: Typos and capitalization mistakes ('Left' vs 'left'), passing a numeric flag, reading 'closed' from a config file that uses synonyms like 'open'/'closed'.
Related errors
- Intervals must all be closed on the same side.
- No such keys(s): {pat!r}
- {k} is not a valid identifier
- {k} is a python keyword
- Value must be an instance of {type_repr}
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/1e0439088381c5ff.
Report an issue: GitHub.