pola-rs/polars · error

MutableUtf8ValuesArray can only be initialized with DataType

Error message

MutableUtf8ValuesArray can only be initialized with DataType::Utf8 or DataType::LargeUtf8

What it means

new_unchecked compares dtype.to_physical_type() against the array's default dtype (Utf8 for i32 offsets, LargeUtf8 for i64 offsets). Anything else — Utf8View, Binary, Dictionary, or an extension whose storage is not Utf8/LargeUtf8 — panics with this message.

Source

Thrown at crates/polars-arrow/src/array/utf8/mutable_values.rs:113

    /// * `offsets.last()` is greater than `values.len()`
    /// * The `dtype`'s [`crate::datatypes::PhysicalType`] is equal to either `Utf8` or `LargeUtf8`.
    ///
    /// # Safety
    /// This function is safe iff:
    /// * the offsets are monotonically increasing
    /// * The `values` between two consecutive `offsets` are not valid utf8
    /// # Implementation
    /// This function is `O(1)`
    pub unsafe fn new_unchecked(
        dtype: ArrowDataType,
        offsets: Offsets<O>,
        values: Vec<u8>,
    ) -> Self {
        try_check_offsets_bounds(&offsets, values.len())
            .expect("The length of the values must be equal to the last offset value");

        if dtype.to_physical_type() != Self::default_dtype().to_physical_type() {
            panic!(
                "MutableUtf8ValuesArray can only be initialized with DataType::Utf8 or DataType::LargeUtf8"
            )
        }

        Self {
            dtype,
            offsets,
            values,
        }
    }

    /// Returns the default [`ArrowDataType`] of this container: [`ArrowDataType::Utf8`] or [`ArrowDataType::LargeUtf8`]
    /// depending on the generic [`Offset`].
    pub fn default_dtype() -> ArrowDataType {
        Utf8Array::<O>::default_dtype()
    }

    /// Initializes a new [`MutableUtf8ValuesArray`] with a pre-allocated capacity of items.

View on GitHub (pinned to 9b5d73fd00)

Solutions

  1. Use ArrowDataType::Utf8 with O = i32, or LargeUtf8 with O = i64 — the physical type must match the offset width
  2. For view-encoded strings use the view arrays (Utf8ViewArray / MutableBinViewArray<str>) instead
  3. For extension types, construct with the underlying Utf8/LargeUtf8 storage dtype and re-tag afterwards

Example fix

// before
let arr = unsafe { MutableUtf8ValuesArray::<i32>::new_unchecked(ArrowDataType::Utf8View, offsets, values) };

// after
let arr = unsafe { MutableUtf8ValuesArray::<i32>::new_unchecked(ArrowDataType::Utf8, offsets, values) };
Defensive patterns

Strategy: validation

Validate before calling

fn utf8_dtype_ok<O: polars_arrow::offset::Offset>(dtype: &ArrowDataType) -> bool {
    dtype.to_physical_type()
        == MutableUtf8ValuesArray::<O>::default_dtype().to_physical_type()
}

Type guard

fn is_utf8_physical(dtype: &ArrowDataType) -> bool {
    matches!(dtype.to_physical_type(), polars_arrow::datatypes::PhysicalType::Utf8 | polars_arrow::datatypes::PhysicalType::LargeUtf8)
}

Prevention

When it happens

Trigger: Passing ArrowDataType::Utf8View (or Binary/BinaryView) offsets/values into the Utf8 values array; passing a Dictionary(Utf8) dtype; mixing a LargeUtf8 dtype with the i32-offset generic instantiation.

Common situations: Migrating string data to the view layout and reusing the old constructor; generic code parameterized over dtype that lands in the wrong constructor arm.

Related errors


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