{"record":{"id":"3c9d04a34bdcac7b","repo":"pandas-dev/pandas","slug":"invalid-dtype-dtype","errorCode":null,"errorMessage":"invalid dtype: {dtype}","messagePattern":"invalid dtype: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/interval.py","lineNumber":609,"sourceCode":"            right.append(rhs)\n\n        return cls.from_arrays(left, right, closed, copy=False, dtype=dtype)\n\n    @classmethod\n    def _validate(cls, left, right, dtype: IntervalDtype) -> None:\n        \"\"\"\n        Verify that the IntervalArray is valid.\n\n        Checks that\n\n        * 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","sourceCodeStart":591,"sourceCodeEnd":627,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/interval.py#L591-L627","documentation":"Raised by the internal `IntervalArray._validate` when the supplied dtype is not an `IntervalDtype`. This typically means a downstream caller passed a plain numpy/object dtype into a code path that requires a properly-formed IntervalDtype. Fires at pandas/core/arrays/interval.py:609.","triggerScenarios":"Internal calls into `_validate(left, right, dtype='int64')`, or a subclass/factory that hands a non-Interval dtype to the validator. Public API users usually hit it via `pd.IntervalIndex(..., dtype='int64')` instead of `dtype='interval[int64]'`.","commonSituations":"Passing the subtype dtype directly rather than wrapping it in IntervalDtype; copy-paste errors from numeric code paths.","solutions":["Wrap the subtype: `dtype=pd.IntervalDtype('int64')` or `dtype='interval[int64]'`.","Drop `dtype=` entirely and let pandas infer the subtype from the bounds.","If subclassing, ensure `_validate` receives `IntervalDtype`, not the raw subtype."],"exampleFix":"// before\npd.IntervalIndex(left, right, dtype='int64')\n// after\npd.IntervalIndex(left, right, dtype='interval[int64]')","handlingStrategy":"validation","validationCode":"import pandas as pd\n\ndef as_interval_dtype(dtype):\n    if dtype is None:\n        return None\n    if not isinstance(dtype, pd.IntervalDtype):\n        dtype = pd.IntervalDtype(dtype)\n    return dtype","typeGuard":"import pandas as pd\n\ndef is_interval_dtype(dtype) -> bool:\n    return isinstance(dtype, pd.IntervalDtype)","tryCatchPattern":"try:\n    ii = pd.IntervalIndex(left, right, dtype=dtype)\nexcept ValueError as e:\n    if \"invalid dtype\" in str(e):\n        ii = pd.IntervalIndex(left, right, dtype=pd.IntervalDtype(dtype))\n    else:\n        raise","preventionTips":["Wrap subtypes in pd.IntervalDtype or use 'interval[subtype]' strings.","Let pandas infer the subtype when in doubt — omit dtype.","Add an assertion isinstance(dtype, IntervalDtype) in factory helpers."],"tags":["interval","dtype","validation","internal"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}