{"record":{"id":"cd4607a189ed4928","repo":"pola-rs/polars","slug":"can-not-get-dtype-of-categorical-anyvalue","errorCode":null,"errorMessage":"can not get dtype of Categorical AnyValue","messagePattern":"can not get dtype of Categorical AnyValue","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-core/src/datatypes/any_value.rs","lineNumber":252,"sourceCode":"            Float32(_) => DataType::Float32,\n            Float64(_) => DataType::Float64,\n            String(_) | StringOwned(_) => DataType::String,\n            Binary(_) | BinaryOwned(_) => DataType::Binary,\n            #[cfg(feature = \"dtype-date\")]\n            Date(_) => DataType::Date,\n            #[cfg(feature = \"dtype-time\")]\n            Time(_) => DataType::Time,\n            #[cfg(feature = \"dtype-datetime\")]\n            Datetime(_, tu, tz) => DataType::Datetime(*tu, (*tz).cloned()),\n            #[cfg(feature = \"dtype-datetime\")]\n            DatetimeOwned(_, tu, tz) => {\n                DataType::Datetime(*tu, tz.as_ref().map(|v| v.as_ref().clone()))\n            },\n            #[cfg(feature = \"dtype-duration\")]\n            Duration(_, tu) => DataType::Duration(*tu),\n            #[cfg(feature = \"dtype-categorical\")]\n            Categorical(_, _) | CategoricalOwned(_, _) => {\n                unimplemented!(\"can not get dtype of Categorical AnyValue\")\n            },\n            #[cfg(feature = \"dtype-categorical\")]\n            Enum(_, _) | EnumOwned(_, _) => unimplemented!(\"can not get dtype of Enum AnyValue\"),\n            List(s) => DataType::List(Box::new(s.dtype().clone())),\n            #[cfg(feature = \"dtype-map\")]\n            Map(s) => {\n                let DataType::Struct(fields) = s.dtype() else {\n                    unimplemented!(\"Map AnyValue payload must be a Struct\")\n                };\n                DataType::Map(\n                    Box::new(fields[0].dtype().clone()),\n                    Box::new(fields[1].dtype().clone()),\n                )\n            },\n            #[cfg(feature = \"dtype-array\")]\n            Array(s, size) => DataType::Array(Box::new(s.dtype().clone()), *size),\n            #[cfg(feature = \"dtype-struct\")]\n            Struct(_, _, fields) => DataType::Struct(fields.to_vec()),","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/crates/polars-core/src/datatypes/any_value.rs#L234-L270","documentation":"AnyValue::dtype() reconstructs the logical DataType from an AnyValue, but Categorical AnyValues carry only the raw physical id — the mapping from id to the actual categories lives in the CategoricalRevMapping, which the function cannot recover. The library therefore marks this case unimplemented rather than returning a wrong dtype.","triggerScenarios":"Calling .dtype() on an AnyValue::Categorical or AnyValue::CategoricalOwned — directly, or transitively via code paths like AnyValue::from that call dtype() on a value originating from a Categorical column.","commonSituations":"Reading a single element of a Categorical series via get()/iter() and asking for its dtype; generic code that calls av.dtype() on any scalar it receives; mapping over categorical values where the surrounding Series should be consulted instead.","solutions":["Get the dtype from the owning Series/ChunkedArray (series.dtype()) instead of the individual AnyValue.","Convert the value via Series first: s.cast(&DataType::String) then read strings, or use s.get(idx) on a String-typed copy.","In your own code, match Categorical variants explicitly and take the dtype from the CategoricalRevMapping you hold.","Avoid writing dtype()-driven generic code over scalars from categorical columns."],"exampleFix":"// before\nlet dtype = av.dtype(); // panics for Categorical\n// after\nlet dtype = categorical_series.dtype(); // DataType::Categorical(rev, ordering)","handlingStrategy":"type-guard","validationCode":"fn scalar_dtype(av: &AnyValue) -> Option<DataType> {\n    match av {\n        AnyValue::Categorical(..) | AnyValue::CategoricalOwned(..) => None,\n        _ => Some(av.dtype()),\n    }\n}","typeGuard":"if matches!(av, AnyValue::Categorical(..) | AnyValue::CategoricalOwned(..)) { /* use series dtype */ }","tryCatchPattern":null,"preventionTips":["Always take dtypes from Series, not individual AnyValues","Treat Categorical/Enum scalars as opaque physical ids","Cast categorical series to String before per-value processing"],"tags":["polars","panic","categorical","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}