pola-rs/polars · error

Dynamic MinMax is not yet implemented for {:?}

Error message

Dynamic MinMax is not yet implemented for {:?}

What it means

dyn_array_min_ignore_nan / dyn_array_max_ignore_nan (and the propagate_nan variants) dyn-dispatch min/max over Arrow physical types. Boolean, every primitive, BinaryView/Utf8View and i32/i64 Binary/Utf8 are wired; any other physical type - Null, List, LargeList, FixedSizeList, Struct, Map, Union, Dictionary - falls through to todo!("Dynamic MinMax is not yet implemented").

Source

Thrown at crates/polars-compute/src/min_max/dyn_array.rs:69

            PH::Primitive(PR::Int128) => call_op!(dt: PArr<i128>, PScalar<i128>, arr, $op$(, $variant)?),
            PH::Primitive(PR::UInt8) => call_op!(dt: PArr<u8>, PScalar<u8>, arr, $op$(, $variant)?),
            PH::Primitive(PR::UInt16) => call_op!(dt: PArr<u16>, PScalar<u16>, arr, $op$(, $variant)?),
            PH::Primitive(PR::UInt32) => call_op!(dt: PArr<u32>, PScalar<u32>, arr, $op$(, $variant)?),
            PH::Primitive(PR::UInt64) => call_op!(dt: PArr<u64>, PScalar<u64>, arr, $op$(, $variant)?),
            PH::Primitive(PR::UInt128) => call_op!(dt: PArr<u128>, PScalar<u128>, arr, $op$(, $variant)?),
            PH::Primitive(PR::Float32) => call_op!(dt: PArr<f32>, PScalar<f32>, arr, $op$(, $variant)?),
            PH::Primitive(PR::Float16) => call_op!(dt: PArr<pf16>, PScalar<pf16>, arr, $op$(, $variant)?),
            PH::Primitive(PR::Float64) => call_op!(dt: PArr<f64>, PScalar<f64>, arr, $op$(, $variant)?),

            PH::BinaryView => call_op!(BinaryViewArray, BinaryViewScalar<[u8]>, arr, $op$(, $variant)?),
            PH::Utf8View => call_op!(Utf8ViewArray, BinaryViewScalar<str>, arr, $op$(, $variant)?),

            PH::Binary => call_op!(BinaryArray<i32>, BinaryScalar<i32>, arr, $op$(, $variant)?),
            PH::LargeBinary => call_op!(BinaryArray<i64>, BinaryScalar<i64>, arr, $op$(, $variant)?),
            PH::Utf8 => call_op!(Utf8Array<i32>, BinaryScalar<i32>, arr, $op$(, $variant)?),
            PH::LargeUtf8 => call_op!(Utf8Array<i64>, BinaryScalar<i64>, arr, $op$(, $variant)?),

            _ => todo!("Dynamic MinMax is not yet implemented for {:?}", arr.dtype()),
        }
    }};
}

pub fn dyn_array_min_ignore_nan(arr: &dyn Array) -> Option<Box<dyn Scalar>> {
    call!(arr, MinMaxKernel::min_ignore_nan_kernel)
}

pub fn dyn_array_max_ignore_nan(arr: &dyn Array) -> Option<Box<dyn Scalar>> {
    call!(arr, MinMaxKernel::max_ignore_nan_kernel)
}

pub fn dyn_array_min_propagate_nan(arr: &dyn Array) -> Option<Box<dyn Scalar>> {
    call!(arr, MinMaxKernel::min_propagate_nan_kernel)
}

pub fn dyn_array_max_propagate_nan(arr: &dyn Array) -> Option<Box<dyn Scalar>> {
    call!(arr, MinMaxKernel::max_propagate_nan_kernel)

View on GitHub (pinned to 9b5d73fd00)

Solutions

  1. Narrow the dtype before calling: only invoke the dyn min/max entry points for Boolean/Primitive/string/binary physical types
  2. For nested dtypes, restructure the computation (explode lists, take struct fields) instead of dyn min/max
  3. Implement the missing MinMaxKernel arms or extend the dyn dispatch upstream

Example fix

// before
let m = dyn_array_min_ignore_nan(arr); // panics for List/Struct/Dictionary arrays
// after
use arrow::datatypes::PhysicalType::*;
fn supported(dtype: &ArrowDataType) -> bool {
    matches!(dtype.to_physical_type(), Boolean | Primitive(_) | BinaryView | Utf8View | Binary | LargeBinary | Utf8 | LargeUtf8)
}
let m = if supported(arr.dtype()) { dyn_array_min_ignore_nan(arr) } else { None /* compute differently */ };
Defensive patterns

Strategy: type-guard

Validate before calling

use arrow::datatypes::PhysicalType::*;
fn min_max_supported(dtype: &ArrowDataType) -> bool {
    matches!(dtype.to_physical_type(),
        Boolean | Primitive(_) | BinaryView | Utf8View | Binary | LargeBinary | Utf8 | LargeUtf8)
}
if min_max_supported(arr.dtype()) {
    let m = dyn_array_min_ignore_nan(arr);
} else {
    // restructure: explode / take fields / reject with a clear error
}

Type guard

// Rust: narrow before dispatch
fn is_scalar_min_max_dtype(dtype: &ArrowDataType) -> bool {
    min_max_supported(dtype)
}

Prevention

When it happens

Trigger: Calling these polars-compute entry points (directly from Rust, or via higher-level Series aggregation code routed through them) on an array whose physical type is outside the dispatch - e.g. a ListArray, StructArray, NullArray, or Arrow dictionary array.

Common situations: Generic Rust code computing min/max over Box<dyn Array> without first narrowing the dtype; integration code feeding Arrow interop data (dictionary-encoded strings, nested types) into polars-compute min/max kernels.

Related errors


AI-assisted analysis of pola-rs/polars@9b5d73fd00 (2026-08-19). Data as JSON: /api/errors/668f9435b7283f6f. Report an issue: GitHub.