{"record":{"id":"097377ed10832f1a","repo":"pandas-dev/pandas","slug":"category-object-and-string-subtypes-are-not-supp","errorCode":null,"errorMessage":"category, object, and string subtypes are not supported for IntervalArray","messagePattern":"category, object, and string subtypes are not supported for IntervalArray","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/interval.py","lineNumber":334,"sourceCode":"            left = left.astype(right.dtype)\n\n        if type(left) != type(right):\n            msg = (\n                f\"must not have differing left [{type(left).__name__}] and \"\n                f\"right [{type(right).__name__}] types\"\n            )\n            raise ValueError(msg)\n        if (\n            isinstance(left.dtype, CategoricalDtype)\n            or is_string_dtype(left.dtype)\n            or is_string_dtype(right.dtype)\n        ):\n            # GH 19016, GH 66518: reject unsupported right-side dtypes too.\n            msg = (\n                \"category, object, and string subtypes are not supported \"\n                \"for IntervalArray\"\n            )\n            raise TypeError(msg)\n        if isinstance(left, ABCPeriodIndex):\n            msg = \"Period dtypes are not supported, use a PeriodIndex instead\"\n            raise ValueError(msg)\n        if isinstance(left, ABCDatetimeIndex) and str(left.tz) != str(right.tz):\n            msg = (\n                \"left and right must have the same time zone, got \"\n                f\"'{left.tz}' and '{right.tz}'\"\n            )\n            raise ValueError(msg)\n        elif needs_i8_conversion(left.dtype) and left.unit != right.unit:\n            # e.g. m8[s] vs m8[ms], try to cast to a common dtype GH#55714\n            left_arr, right_arr = left._data._ensure_matching_resos(right._data)\n            left = ensure_index(left_arr)\n            right = ensure_index(right_arr)\n\n        # For dt64/td64 we want DatetimeArray/TimedeltaArray instead of ndarray\n        left = ensure_wrapped_if_datetimelike(left)\n        left = extract_array(left, extract_numpy=True)","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/interval.py#L316-L352","documentation":"Raised as a TypeError when either side of an interval is a categorical, object, or string dtype. IntervalArray only supports numeric, datetime, or timedelta subtypes; strings/categories have no total ordering that is meaningful for interval arithmetic. Fires at pandas/core/arrays/interval.py:334 (GH 19016, GH 66518).","triggerScenarios":"`pd.IntervalIndex.from_arrays(['a','b'], ['c','d'])`, passing a Categorical column, passing a `string` dtype, or passing object-dtype arrays of strings.","commonSituations":"Reading heterogeneous CSV columns where interval bounds were inferred as object/string; building bins from label-encoded categoricals.","solutions":["Convert bounds to a numeric dtype: `left = pd.to_numeric(left)`, `right = pd.to_numeric(right)`.","If the data is genuinely categorical labels, do not use IntervalArray — use a CategoricalIndex or `pd.cut` on numeric codes.","Strip whitespace / parse dates: `pd.to_datetime(left)` if the bounds are timestamps stored as strings."],"exampleFix":"// before\npd.IntervalIndex.from_arrays(df['low_str'], df['high_str'])\n// after\npd.IntervalIndex.from_arrays(pd.to_numeric(df['low_str']), pd.to_numeric(df['high_str']))","handlingStrategy":"validation","validationCode":"def to_numeric_bounds(left, right):\n    import pandas as pd\n    left = pd.to_numeric(left, errors='coerce')\n    right = pd.to_numeric(right, errors='coerce')\n    return left, right","typeGuard":"import pandas as pd\nimport numpy as np\n\ndef is_supported_subtype(arr) -> bool:\n    return arr.dtype.kind in 'iufMm' or pd.api.types.is_datetime64_any_dtype(arr.dtype)","tryCatchPattern":"try:\n    ia = pd.IntervalArray(left, right)\nexcept TypeError as e:\n    if \"subtypes are not supported\" in str(e):\n        ia = pd.IntervalArray(pd.to_numeric(left), pd.to_numeric(right))\n    else:\n        raise","preventionTips":["Validate `arr.dtype.kind in 'iufMm'` for both bounds before constructing.","Run pd.to_numeric on string-encoded bounds at ingestion time.","Reject Categorical/string columns explicitly in your data schema."],"tags":["interval","dtype","categorical","string","constructor"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}