{"record":{"id":"4e7a9c6625828e19","repo":"pola-rs/polars","slug":"wrong-datatype","errorCode":null,"errorMessage":"Wrong DataType","messagePattern":"Wrong DataType","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-arrow/src/array/fixed_size_binary/mod.rs","lineNumber":193,"sourceCode":"    pub fn get(&self, i: usize) -> Option<&[u8]> {\n        if !self.is_null(i) {\n            // soundness: Array::is_null panics if i >= self.len\n            unsafe { Some(self.value_unchecked(i)) }\n        } else {\n            None\n        }\n    }\n\n    /// Returns a new [`FixedSizeBinaryArray`] with a different logical type.\n    /// This is `O(1)`.\n    /// # Panics\n    /// Panics iff the dtype is not supported for the physical type.\n    #[inline]\n    pub fn to(self, dtype: ArrowDataType) -> Self {\n        match (dtype.to_storage(), self.dtype().to_storage()) {\n            (ArrowDataType::FixedSizeBinary(size_a), ArrowDataType::FixedSizeBinary(size_b))\n                if size_a == size_b => {},\n            _ => panic!(\"Wrong DataType\"),\n        }\n\n        Self {\n            size: self.size,\n            dtype,\n            values: self.values,\n            validity: self.validity,\n        }\n    }\n\n    /// Returns the size\n    pub fn size(&self) -> usize {\n        self.size\n    }\n}\n\nimpl FixedSizeBinaryArray {\n    pub(crate) fn maybe_get_size(dtype: &ArrowDataType) -> PolarsResult<usize> {","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/pola-rs/polars/blob/9b5d73fd00236295624374b075d16b1fe6ec6df9/crates/polars-arrow/src/array/fixed_size_binary/mod.rs#L175-L211","documentation":"Compile-time panic from #[polars_expr] in pyo3-polars-derive (lib.rs:130). The macro supports at most three parameters: the mandatory input slice plus at most context and kwargs. Any function with three or more parameters after the first panics with \"didn't expect so many arguments\" — the extra arguments are not even inspected, the count alone is rejected. Additional configuration has no positional channel; it must ride inside the kwargs struct.","triggerScenarios":"fn f(inputs: &[Series], context: CallerContext, kwargs: MyKwargs, factor: f64) -> PolarsResult<Series>, or any 4+-parameter function under #[polars_expr(...)], even if all names after inputs are spelled correctly.","commonSituations":"Growing a plugin's configuration over time by appending parameters; developers used to plain Rust APIs assuming positional arguments pass through; porting a function that already took several options and trying to expose it unchanged as a Polars expression.","solutions":["Reduce the function to at most (inputs, context, kwargs); move every extra value into the kwargs struct as a field","Pre-compute or close over constants outside the plugin function if the value does not need to come from Python per call","Update the Python-side register_plugin_function call so the moved fields are passed in kwargs","Keep using context only for CallerContext concerns (e.g. context.parallel()), not for user configuration"],"exampleFix":"// before — four parameters, count alone is rejected\n#[polars_expr(output_type=Float64)]\nfn dist(inputs: &[Series], context: CallerContext, kwargs: MyKwargs, factor: f64) -> PolarsResult<Series> {\n    todo!()\n}\n\n// after — fold the extra value into the kwargs struct\n#[derive(Deserialize)]\nstruct MyKwargs {\n    factor: f64,\n}\n\n#[polars_expr(output_type=Float64)]\nfn dist(inputs: &[Series], context: CallerContext, kwargs: MyKwargs) -> PolarsResult<Series> {\n    todo!()\n}","handlingStrategy":"validation","validationCode":"# ci/check_polars_expr.py — run before cargo build\nimport re, sys, pathlib\npat = re.compile(r\"#\\[polars_expr\\([^)]*\\)\\]\\s*(?:pub\\s+)?fn\\s+\\w+\\(([^)]*)\\)\", re.S)\nfor f in pathlib.Path(\"src\").rglob(\"*.rs\"):\n    for m in pat.finditer(f.read_text()):\n        params = [p.strip() for p in m.group(1).split(\",\") if p.strip()]\n        if len(params) > 3:\n            sys.exit(f\"{f}: polars_expr fn has {len(params)} parameters; max is 3 (inputs, context, kwargs). Move extras into the kwargs struct\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Hard cap of three parameters: inputs, optionally context, optionally kwargs","Design plugin configuration as a single Deserialize struct from day one so new options never need new parameters","Keep constants out of the signature entirely — close over them or recompute inside the function"],"tags":["rust","proc-macro","polars","compile-time","arity"],"backgroundTag":"proc-macro-panicked","analyzedSha":"9b5d73fd00236295624374b075d16b1fe6ec6df9","analyzedAt":"2026-08-19T12:15:06.350Z","contentChangedAt":"2026-08-19T12:15:06.350Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}