pola-rs/polars · error

can not get dtype of Categorical AnyValue

Error message

can not get dtype of Categorical AnyValue

What it means

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.

Solutions

  1. Get the dtype from the owning Series/ChunkedArray (series.dtype()) instead of the individual AnyValue.
  2. Convert the value via Series first: s.cast(&DataType::String) then read strings, or use s.get(idx) on a String-typed copy.
  3. In your own code, match Categorical variants explicitly and take the dtype from the CategoricalRevMapping you hold.
  4. Avoid writing dtype()-driven generic code over scalars from categorical columns.

Example fix

// before
let dtype = av.dtype(); // panics for Categorical
// after
let dtype = categorical_series.dtype(); // DataType::Categorical(rev, ordering)
Defensive patterns

Strategy: type-guard

Validate before calling

fn scalar_dtype(av: &AnyValue) -> Option<DataType> {
    match av {
        AnyValue::Categorical(..) | AnyValue::CategoricalOwned(..) => None,
        _ => Some(av.dtype()),
    }
}

Type guard

if matches!(av, AnyValue::Categorical(..) | AnyValue::CategoricalOwned(..)) { /* use series dtype */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/cd4607a189ed4928. Report an issue: GitHub.

Appendix: source

Thrown at crates/polars-core/src/datatypes/any_value.rs:252

            Float32(_) => DataType::Float32,
            Float64(_) => DataType::Float64,
            String(_) | StringOwned(_) => DataType::String,
            Binary(_) | BinaryOwned(_) => DataType::Binary,
            #[cfg(feature = "dtype-date")]
            Date(_) => DataType::Date,
            #[cfg(feature = "dtype-time")]
            Time(_) => DataType::Time,
            #[cfg(feature = "dtype-datetime")]
            Datetime(_, tu, tz) => DataType::Datetime(*tu, (*tz).cloned()),
            #[cfg(feature = "dtype-datetime")]
            DatetimeOwned(_, tu, tz) => {
                DataType::Datetime(*tu, tz.as_ref().map(|v| v.as_ref().clone()))
            },
            #[cfg(feature = "dtype-duration")]
            Duration(_, tu) => DataType::Duration(*tu),
            #[cfg(feature = "dtype-categorical")]
            Categorical(_, _) | CategoricalOwned(_, _) => {
                unimplemented!("can not get dtype of Categorical AnyValue")
            },
            #[cfg(feature = "dtype-categorical")]
            Enum(_, _) | EnumOwned(_, _) => unimplemented!("can not get dtype of Enum AnyValue"),
            List(s) => DataType::List(Box::new(s.dtype().clone())),
            #[cfg(feature = "dtype-map")]
            Map(s) => {
                let DataType::Struct(fields) = s.dtype() else {
                    unimplemented!("Map AnyValue payload must be a Struct")
                };
                DataType::Map(
                    Box::new(fields[0].dtype().clone()),
                    Box::new(fields[1].dtype().clone()),
                )
            },
            #[cfg(feature = "dtype-array")]
            Array(s, size) => DataType::Array(Box::new(s.dtype().clone()), *size),
            #[cfg(feature = "dtype-struct")]
            Struct(_, _, fields) => DataType::Struct(fields.to_vec()),

View on GitHub (pinned to fe841f959e)