{"record":{"id":"54104f029e851ef2","repo":"pandas-dev/pandas","slug":"missing-values-must-be-missing-in-the-same-locatio","errorCode":null,"errorMessage":"missing values must be missing in the same location both left and right sides","messagePattern":"missing values must be missing in the same location both left and right sides","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/interval.py","lineNumber":620,"sourceCode":"        * dtype is correct\n        * left and right match lengths\n        * left and right have the same missing values\n        * left is always below right\n        \"\"\"\n        if not isinstance(dtype, IntervalDtype):\n            msg = f\"invalid dtype: {dtype}\"\n            raise ValueError(msg)\n        if len(left) != len(right):\n            msg = \"left and right must have the same length\"\n            raise ValueError(msg)\n        left_mask = notna(left)\n        right_mask = notna(right)\n        if not (left_mask == right_mask).all():\n            msg = (\n                \"missing values must be missing in the same \"\n                \"location both left and right sides\"\n            )\n            raise ValueError(msg)\n        if not (left[left_mask] <= right[left_mask]).all():\n            msg = \"left side of interval must be <= right side\"\n            raise ValueError(msg)\n\n    def _shallow_copy(self, left, right) -> Self:\n        \"\"\"\n        Return a new IntervalArray with the replacement attributes\n\n        Parameters\n        ----------\n        left : Index\n            Values to be used for the left-side of the intervals.\n        right : Index\n            Values to be used for the right-side of the intervals.\n        \"\"\"\n        dtype = IntervalDtype(left.dtype, closed=self.closed)\n        left, right, dtype = self._ensure_simple_new_inputs(left, right, dtype=dtype)\n","sourceCodeStart":602,"sourceCodeEnd":638,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/interval.py#L602-L638","documentation":"Raised in `_validate` when the NA masks of left and right differ — `(left_mask == right_mask).all()` fails. Intervals must be missing on both sides at the same positions; a half-missing interval is not representable.","triggerScenarios":"left has NaN at index 2 but right has a value there; imputing only one side; joining bounds where one side has more NaNs.","commonSituations":"Data cleaning that fills NaN on the upper bound but not lower; arithmetic producing NaN on one side only (e.g. left shifted); merging series with different missingness.","solutions":["Make NA positions symmetric: `mask = left.isna() | right.isna()` then `left[mask] = right[mask] = NA`.","Drop rows where either side is NA before constructing.","Investigate upstream: a single-sided NaN usually indicates a data bug."],"exampleFix":"# before\nleft = pd.Series([0, np.nan, 2]); right = pd.Series([1, 5, 3])\nIntervalArray.from_arrays(left, right)\n\n# after - symmetric mask\nmask = left.isna() | right.isna()\nleft, right = left.mask(mask, np.nan), right.mask(mask, np.nan)\nIntervalArray.from_arrays(left, right)","handlingStrategy":"validation","validationCode":"import numpy as np\nimport pandas as pd\n\ndef symmetrise_na(left, right):\n    left, right = pd.Series(left), pd.Series(right)\n    mask = left.isna() | right.isna()\n    return left.mask(mask, np.nan), right.mask(mask, np.nan)","typeGuard":"import pandas as pd\n\ndef na_masks_match(left, right) -> bool:\n    return (pd.isna(left) == pd.isna(right)).all()","tryCatchPattern":"try:\n    arr = IntervalArray.from_arrays(left, right)\nexcept ValueError as e:\n    if 'missing in the same location' in str(e):\n        l, r = symmetrise_na(left, right)\n        arr = IntervalArray.from_arrays(l, r)\n    else:\n        raise","preventionTips":["Make NA positions symmetric before constructing intervals.","Drop rows where either bound is NA if symmetry cannot be enforced.","Investigate single-sided NaN as a likely upstream data bug."],"tags":["interval","missing-values","na-mask","value-error"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}