{"record":{"id":"1e0439088381c5ff","repo":"pandas-dev/pandas","slug":"invalid-option-for-closed-closed","errorCode":null,"errorMessage":"invalid option for 'closed': {closed}","messagePattern":"invalid option for 'closed': (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/interval.py","lineNumber":1483,"sourceCode":"        --------\n        IntervalArray.closed : Returns inclusive side of the Interval.\n        arrays.IntervalArray.closed : Returns inclusive side of the IntervalArray.\n\n        Examples\n        --------\n        >>> index = pd.arrays.IntervalArray.from_breaks(range(4))\n        >>> index\n        <IntervalArray>\n        [(0, 1], (1, 2], (2, 3]]\n        Length: 3, dtype: interval[int64, right]\n        >>> index.set_closed(\"both\")\n        <IntervalArray>\n        [[0, 1], [1, 2], [2, 3]]\n        Length: 3, dtype: interval[int64, both]\n        \"\"\"\n        if closed not in VALID_CLOSED:\n            msg = f\"invalid option for 'closed': {closed}\"\n            raise ValueError(msg)\n\n        left, right = self._left, self._right\n        dtype = IntervalDtype(left.dtype, closed=closed)\n        return self._simple_new(left, right, dtype=dtype)\n\n    @property\n    def is_non_overlapping_monotonic(self) -> bool:\n        \"\"\"\n        Return a boolean whether the IntervalArray/IntervalIndex\\\n        is non-overlapping and monotonic.\n\n        Non-overlapping means (no Intervals share points), and monotonic means\n        either monotonic increasing or monotonic decreasing.\n\n        See Also\n        --------\n        overlaps : Check if two IntervalIndex objects overlap.\n","sourceCodeStart":1465,"sourceCodeEnd":1501,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/interval.py#L1465-L1501","documentation":"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.","triggerScenarios":"Calling arr.set_closed('Right') (wrong case), arr.set_closed('closed'), arr.set_closed(None), or arr.set_closed('outside').","commonSituations":"Typos and capitalization mistakes ('Left' vs 'left'), passing a numeric flag, reading 'closed' from a config file that uses synonyms like 'open'/'closed'.","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."],"exampleFix":"# before\narr = pd.arrays.IntervalArray.from_tuples([(0, 1)])\narr.set_closed('Right')\n\n# after\narr.set_closed('right')","handlingStrategy":"validation","validationCode":"VALID = {'left', 'right', 'both', 'neither'}\ndef normalize_closed(s):\n    s = str(s).strip().lower()\n    if s not in VALID:\n        raise ValueError(f\"closed must be one of {VALID}, got {s!r}\")\n    return s","typeGuard":"def is_valid_closed(s) -> bool:\n    return isinstance(s, str) and s in {'left', 'right', 'both', 'neither'}","tryCatchPattern":null,"preventionTips":["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."],"tags":["interval-array","validation","argument"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}