{"record":{"id":"6a11630eb714d046","repo":"pola-rs/polars","slug":"named-agg-not-found","errorCode":null,"errorMessage":"NAMED AGG NOT FOUND","messagePattern":"NAMED AGG NOT FOUND","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-plan/src/dsl/expr/anonymous/agg.rs","lineNumber":39,"sourceCode":"    pub fn materialize(&self) -> PolarsResult<SpecialEq<Arc<dyn AnonymousAgg>>> {\n        match self {\n            Self::Deserialized(t) => Ok(t.clone()),\n            Self::Named {\n                name,\n                payload,\n                value,\n            } => feature_gated!(\"serde\", {\n                use super::named_serde::NAMED_SERDE_REGISTRY_EXPR;\n                match value {\n                    Some(v) => Ok(v.clone()),\n                    None => Ok(SpecialEq::new(\n                        NAMED_SERDE_REGISTRY_EXPR\n                            .read()\n                            .unwrap()\n                            .as_ref()\n                            .expect(\"NAMED EXPR REGISTRY NOT SET\")\n                            .get_agg(name, payload.as_ref().unwrap())?\n                            .expect(\"NAMED AGG NOT FOUND\"),\n                    )),\n                }\n            }),\n            Self::Bytes(_b) => {\n                feature_gated!(\"serde\", {\n                    use crate::dsl::anonymous::serde_expr;\n                    serde_expr::deserialize_anon_agg(_b.as_ref()).map(SpecialEq::new)\n                })\n            },\n        }\n    }\n}\n\nimpl Hash for OpaqueStreamingAgg {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        core::mem::discriminant(self).hash(state);\n        match self {\n            Self::Deserialized(ptr) => ptr.hash(state),","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/crates/polars-plan/src/dsl/expr/anonymous/agg.rs#L21-L57","documentation":"After the named-serde registry is installed, each named anonymous aggregation is resolved by (name, payload). This expect fires when the registry is set but get_agg() returns Ok(None) — the receiving process's registry simply has no entry for that name, meaning the producer's UDF is unknown to the consumer.","triggerScenarios":"Deserializing a plan whose named agg (e.g. a custom aggregation registered by an extension) was produced by a different build/plugin that registered different names; version skew between producer and consumer registries.","commonSituations":"Rolling upgrades where nodes run different plugin versions, a renamed/removed UDF between releases, deserializing on a machine without the extension that owns the UDF.","solutions":["Register an ExprRegistry on the consumer that implements get_agg for every name the producer can emit","Align polars/plugin versions across all processes that exchange serialized plans","When introducing a UDF name, add it to every registry before deploying producers that use it","If the UDF is unavailable by design, send the cached value variant or a plain expression instead of the named form"],"exampleFix":"// before: registry set, but name unknown -> panic 'NAMED AGG NOT FOUND'\n\n// after: registry that knows the producer's names\nstruct Reg;\nimpl ExprRegistry for Reg {\n    fn get_agg(&self, name: &str, payload: &[u8]) -> PolarsResult<Option<Arc<dyn AnonymousAgg>>> {\n        match name {\n            \"my_sum\" => Ok(Some(Arc::new(MySum::decode(payload)))),\n            _ => Ok(None),\n        }\n    }\n}\nset_named_serde_registry(Arc::new(Reg) as _);","handlingStrategy":"validation","validationCode":"// registry contract test: every name the producer emits resolves\nfor name in producer_agg_names() {\n    assert!(registry.get_agg(name, &[]).unwrap().is_some(), \"unknown agg {name}\");\n}","typeGuard":null,"tryCatchPattern":"std::panic::catch_unwind(|| deserialize(bytes))\n    .map_err(|_| format!(\"named agg not registered on this node\"))","preventionTips":["Treat UDF names as a versioned compatibility contract","Register all UDF names before deploying producers","Run contract tests across producer/consumer version pairs"],"tags":["serde","udf","registry","version-skew","distributed","panic","rust"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}