pola-rs/polars · error

activate dtype-categorical to convert dictionary arrays

Error message

activate dtype-categorical to convert dictionary arrays

What it means

Importing Arrow dictionary arrays (dictionary-encoded strings/categoricals) into polars is implemented only under the dtype-categorical cargo feature. With that feature disabled, the Series-from-Arrow conversion hits a cfg-gated panic: 'activate dtype-categorical to convert dictionary arrays'.

Source

Thrown at crates/polars-core/src/series/from.rs:438

                                }).map(Some)
                            } else {
                                Ok(None)
                            }
                        }).try_collect_arr_trusted()?;

                        *chunk = arr_128.to(ArrowDataType::Int128).to_boxed();
                    }

                    let s = Int128Chunked::from_chunks(name, chunks)
                        .into_decimal_unchecked(*precision, *scale)
                        .into_series();
                    Ok(s)
                })
            },
            ArrowDataType::Null => Ok(new_null(name, &chunks)),
            #[cfg(not(feature = "dtype-categorical"))]
            ArrowDataType::Dictionary(_, _, _) => {
                panic!("activate dtype-categorical to convert dictionary arrays")
            },
            #[cfg(feature = "dtype-categorical")]
            ArrowDataType::Dictionary(key_type, _, _) => {
                let polars_dtype = DataType::from_arrow(chunks[0].dtype(), md);

                let mut series_iter = chunks.into_iter().map(|arr| {
                    import_arrow_dictionary_array(name.clone(), arr, key_type, &polars_dtype)
                });

                let mut first = series_iter.next().unwrap()?;

                for s in series_iter {
                    first.append_owned(s?)?;
                }

                Ok(first)
            },
            #[cfg(feature = "object")]

View on GitHub (pinned to 68506541d2)

Solutions

  1. Enable the feature: polars = { version = "...", features = ["dtype-categorical"] }
  2. Pre-decode dictionary arrays to plain Utf8 on the Arrow side before handing them to polars
  3. Or move to a full-featured build (default features or the 'lazy' bundle) for the interop binary

Example fix

# before
polars = { version = "0.4X", default-features = false, features = ["fmt"] }

# after
polars = { version = "0.4X", default-features = false, features = ["fmt", "dtype-categorical"] }
Defensive patterns

Strategy: fallback

Validate before calling

fn has_dict_columns(batches: &[arrow_array::RecordBatch]) -> bool {
    batches.iter().any(|b| {
        b.schema().fields().iter().any(|f| matches!(f.data_type(), arrow_schema::DataType::Dictionary(_, _)))
    })
}

Prevention

When it happens

Trigger: Creating a Series/DataFrame from an Arrow RecordBatch or table that contains Dictionary-typed columns (common when interoping with Arrow/duckdb/pandas via Arrow FFI) while the polars dependency was built without the dtype-categorical feature.

Common situations: Minimal-feature Cargo setups (default-features = false plus a short feature list) that later receive dictionary-encoded data; version bumps where feature sets were trimmed; polars-arrow interop code paths that worked with full feature builds but not slim builds.

Related errors


AI-assisted analysis of pola-rs/polars@68506541d2 (2026-08-19). Data as JSON: /api/errors/7a94be055dd00fa3. Report an issue: GitHub.