pola-rs/polars · error

Take not supported for data type {:?}

Error message

Take not supported for data type {:?}

What it means

polars-compute's gather kernel take_unchecked dispatches on physical type and supports Null, Boolean, Primitive, LargeBinary, Struct, LargeList, FixedSizeList, BinaryView and Utf8View. Every other physical type — legacy Utf8/Binary (i32 offsets), LargeUtf8, List (i32), Map, Union, Dictionary — hits t => unimplemented!("Take not supported for data type {:?}", t) at crates/polars-compute/src/gather/mod.rs:85 and panics. It is an unsafe fn whose documented contract covers bounds but not dtypes, so the restriction is implicit and unenforced.

Source

Thrown at crates/polars-compute/src/gather/mod.rs:85

            structure::take_unchecked(array, indices).boxed()
        },
        LargeList => {
            let array = values.as_any().downcast_ref().unwrap();
            Box::new(list::take_unchecked::<i64>(array, indices))
        },
        FixedSizeList => {
            let array = values.as_any().downcast_ref().unwrap();
            fixed_size_list::take_unchecked(array, indices)
        },
        BinaryView => {
            let array: &BinaryViewArray = values.as_any().downcast_ref().unwrap();
            binview::take_binview_unchecked(array, indices).boxed()
        },
        Utf8View => {
            let array: &Utf8ViewArray = values.as_any().downcast_ref().unwrap();
            binview::take_binview_unchecked(array, indices).boxed()
        },
        t => unimplemented!("Take not supported for data type {:?}", t),
    }
}

/// Naive default implementation
unsafe fn take_unchecked_impl_generic<T>(
    values: &T,
    indices: &IdxArr,
    new_null_func: &dyn Fn(ArrowDataType, usize) -> T,
) -> T
where
    T: StaticArray + ArrayFromIterDtype<std::option::Option<Box<dyn array::Array>>>,
{
    if values.null_count() == values.len() || indices.null_count() == indices.len() {
        return new_null_func(values.dtype().clone(), indices.len());
    }

    match (indices.has_nulls(), values.has_nulls()) {
        (true, true) => {

View on GitHub (pinned to df599052da)

Solutions

  1. Cast string/binary columns to Utf8View/BinaryView and lists to LargeList before gathering
  2. Use a checked take API that returns a Result and validates the dtype
  3. Guard values.dtype().to_physical_type() against the supported set before the unsafe call
  4. Upstream: route missing types through take_unchecked_impl_generic or add dedicated arms

Example fix

// before
let out = unsafe { take_unchecked(utf8_values, &indices) }; // panics: Take not supported for Utf8

// after
let values = cast(utf8_values, &ArrowDataType::Utf8View)?;
let out = unsafe { take_unchecked(values.as_ref(), &indices) };
Defensive patterns

Strategy: type-guard

Validate before calling

use polars_arrow::datatypes::PhysicalType;
fn take_supported(dtype: &ArrowDataType) -> bool {
    matches!(
        dtype.to_physical_type(),
        PhysicalType::Null | PhysicalType::Boolean | PhysicalType::Primitive(_)
            | PhysicalType::LargeBinary | PhysicalType::Struct | PhysicalType::LargeList
            | PhysicalType::FixedSizeList | PhysicalType::BinaryView | PhysicalType::Utf8View
    )
}
polars_ensure!(take_supported(values.dtype()),
    InvalidOperation: "take not supported for {:?}; cast to Utf8View/BinaryView/LargeList first", values.dtype());

Type guard

fn take_supported(dtype: &ArrowDataType) -> bool {
    use polars_arrow::datatypes::PhysicalType::*;
    matches!(
        dtype.to_physical_type(),
        Null | Boolean | Primitive(_) | LargeBinary | Struct | LargeList
            | FixedSizeList | BinaryView | Utf8View
    )
}

Try / catch

let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| unsafe { take_unchecked(values, &indices) }));
let out = match res {
    Ok(v) => v,
    Err(_) => polars_bail!(ComputeError: "take_unchecked panicked: unsupported dtype {:?}", values.dtype()),
};

Prevention

When it happens

Trigger: take_unchecked(values, indices) on e.g. a Utf8 (i32) string column, dictionary-encoded array, or List (i32) column that was not cast first — typically via polars take/gather/filter fast paths or direct calls into polars_compute::gather.

Common situations: Legacy IPC/Parquet string data in Utf8 form; interop with engines emitting dictionary-encoded or 32-bit list columns; performance code that skipped the up-front cast to Utf8View/LargeList.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/5cc120cfa23aa837. Report an issue: GitHub.