pola-rs/polars · error

validity must be equal to the array's length

Error message

validity must be equal to the array's length

What it means

Compile-time panic from #[polars_expr] in pyo3-polars-derive (lib.rs:123). The macro dispatches code generation purely on the NAMES of the function's parameters after the first: the only recognized names are "kwargs" and "context". With exactly one extra parameter, any name other than those two panics with "didn't expect argument {a}", where {a} is the offending parameter name. The first parameter (the &[Series] input slice) is skipped, so its name is free.

Source

Thrown at crates/polars-arrow/src/array/mod.rs:508

macro_rules! impl_mut_validity {
    () => {
        /// Returns this array with a new validity.
        /// # Panic
        /// Panics iff `validity.len() != self.len()`.
        #[must_use]
        #[inline]
        pub fn with_validity(mut self, validity: Option<Bitmap>) -> Self {
            self.set_validity(validity);
            self
        }

        /// Sets the validity of this array.
        /// # Panics
        /// This function panics iff `values.len() != self.len()`.
        #[inline]
        pub fn set_validity(&mut self, validity: Option<Bitmap>) {
            if matches!(&validity, Some(bitmap) if bitmap.len() != self.len()) {
                panic!("validity must be equal to the array's length")
            }
            self.validity = validity;
        }

        /// Takes the validity of this array, leaving it without a validity mask.
        #[inline]
        pub fn take_validity(&mut self) -> Option<Bitmap> {
            self.validity.take()
        }
    }
}

// macro implementing `with_validity`, `set_validity` and `apply_validity` for mutable arrays
macro_rules! impl_mutable_array_mut_validity {
    () => {
        /// Returns this array with a new validity.
        /// # Panic
        /// Panics iff `validity.len() != self.len()`.

View on GitHub (pinned to 68506541d2)

Solutions

  1. Rename the second parameter to exactly kwargs (type: your Deserialize kwargs struct) or exactly context (type: CallerContext from pyo3_polars::derive)
  2. If the extra parameter is not needed, delete it so the function is only fn f(inputs: &[Series]) -> PolarsResult<Series>
  3. If the reported name is "inputs", your first parameter is not the inputs slice (often a leftover &self): remove the receiver so inputs: &[Series] is first
  4. Re-run cargo check to confirm the macro accepts the signature

Example fix

// before — parameter must be named exactly `kwargs`
#[polars_expr(output_type=String)]
fn append_kw(input: &[Series], kw_args: MyKwargs) -> PolarsResult<Series> {
    todo!()
}

// after
#[polars_expr(output_type=String)]
fn append_kw(input: &[Series], kwargs: MyKwargs) -> PolarsResult<Series> {
    todo!()
}
Defensive patterns

Strategy: validation

Validate before calling

# ci/check_polars_expr.py — run before cargo build
import re, sys, pathlib
pat = re.compile(r"#\[polars_expr\([^)]*\)\]\s*(?:pub\s+)?fn\s+\w+\(([^)]*)\)", re.S)
allowed = ([], ["kwargs"], ["context"], ["context", "kwargs"])
for f in pathlib.Path("src").rglob("*.rs"):
    for m in pat.finditer(f.read_text()):
        params = [p.strip() for p in m.group(1).split(",") if p.strip()]
        names = [p.split(":")[0].strip() for p in params[1:]]
        if names not in allowed:
            sys.exit(f"{f}: extra params {names} must be [], ['kwargs'], ['context'] or ['context','kwargs'])")

Prevention

When it happens

Trigger: A two-parameter function whose second parameter is misspelled or renamed: fn f(input: &[Series], kw_args: MyKwargs), fn f(input: &[Series], ctx: CallerContext), fn f(input: &[Series], options: MyKwargs). Also fires when the first parameter is actually a receiver, e.g. fn f(&self, inputs: &[Series]): skip(1) drops &self and "inputs" is then reported as the unexpected argument name.

Common situations: IDE rename refactoring that renames kwargs to kw_args or context to ctx; copying a signature from a non-plugin function; style-driven renaming of parameters without knowing the names are load-bearing for the macro; porting plugins between pyo3-polars versions where conventions changed.

Related errors


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