pola-rs/polars · error
NAMED AGG NOT FOUND
Error message
NAMED AGG NOT FOUND
What it means
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.
Source
Thrown at crates/polars-plan/src/dsl/expr/anonymous/agg.rs:39
pub fn materialize(&self) -> PolarsResult<SpecialEq<Arc<dyn AnonymousAgg>>> {
match self {
Self::Deserialized(t) => Ok(t.clone()),
Self::Named {
name,
payload,
value,
} => feature_gated!("serde", {
use super::named_serde::NAMED_SERDE_REGISTRY_EXPR;
match value {
Some(v) => Ok(v.clone()),
None => Ok(SpecialEq::new(
NAMED_SERDE_REGISTRY_EXPR
.read()
.unwrap()
.as_ref()
.expect("NAMED EXPR REGISTRY NOT SET")
.get_agg(name, payload.as_ref().unwrap())?
.expect("NAMED AGG NOT FOUND"),
)),
}
}),
Self::Bytes(_b) => {
feature_gated!("serde", {
use crate::dsl::anonymous::serde_expr;
serde_expr::deserialize_anon_agg(_b.as_ref()).map(SpecialEq::new)
})
},
}
}
}
impl Hash for OpaqueStreamingAgg {
fn hash<H: Hasher>(&self, state: &mut H) {
core::mem::discriminant(self).hash(state);
match self {
Self::Deserialized(ptr) => ptr.hash(state),View on GitHub (pinned to df599052da)
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
Example fix
// before: registry set, but name unknown -> panic 'NAMED AGG NOT FOUND'
// after: registry that knows the producer's names
struct Reg;
impl ExprRegistry for Reg {
fn get_agg(&self, name: &str, payload: &[u8]) -> PolarsResult<Option<Arc<dyn AnonymousAgg>>> {
match name {
"my_sum" => Ok(Some(Arc::new(MySum::decode(payload)))),
_ => Ok(None),
}
}
}
set_named_serde_registry(Arc::new(Reg) as _); Defensive patterns
Strategy: validation
Validate before calling
// registry contract test: every name the producer emits resolves
for name in producer_agg_names() {
assert!(registry.get_agg(name, &[]).unwrap().is_some(), "unknown agg {name}");
} Try / catch
std::panic::catch_unwind(|| deserialize(bytes))
.map_err(|_| format!("named agg not registered on this node")) Prevention
- Treat UDF names as a versioned compatibility contract
- Register all UDF names before deploying producers
- Run contract tests across producer/consumer version pairs
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- NAMED EXPR REGISTRY NOT SET
- NAMED FUNCTION NOT FOUND
- NAMED EXPR REGISTRY NOT SET
- not implemented
- not implemented
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/6a11630eb714d046.
Report an issue: GitHub.