pola-rs/polars · error
NAMED EXPR REGISTRY NOT SET
Error message
NAMED EXPR REGISTRY NOT SET
What it means
Same named-serde mechanism as error 626 but for anonymous column UDFs: deserializing a named function variant requires the global NAMED_SERDE_REGISTRY_EXPR to have been installed via set_named_serde_registry. In a process that never registered it, the RwLock holds None and this expect panics during expression deserialization.
Source
Thrown at crates/polars-plan/src/dsl/expr/anonymous/expr.rs:182
impl OpaqueColumnUdf {
pub fn materialize(self) -> PolarsResult<SpecialEq<Arc<dyn AnonymousColumnsUdf>>> {
match self {
Self::Deserialized(t) => Ok(t),
Self::Named {
name,
payload,
value,
} => feature_gated!("serde", {
use super::named_serde::NAMED_SERDE_REGISTRY_EXPR;
match value {
Some(v) => Ok(v),
None => Ok(SpecialEq(
NAMED_SERDE_REGISTRY_EXPR
.read()
.unwrap()
.as_ref()
.expect("NAMED EXPR REGISTRY NOT SET")
.get_function(&name, payload.unwrap().as_ref())
.expect("NAMED FUNCTION NOT FOUND"),
)),
}
}),
Self::Bytes(_b) => {
feature_gated!("serde";"python", {
serde_expr::deserialize_column_udf(_b.as_ref()).map(SpecialEq::new)
})
},
}
}
}
View on GitHub (pinned to df599052da)
Solutions
- Call set_named_serde_registry(...) once per process before deserializing any expression
- Use the registry-supporting entrypoint (e.g. the polars build that registers its UDFs on startup) rather than a bare polars_plan dependency
- Serialize the cached value variant when the consumer cannot provide the registry
- Pin identical polars/extension versions on producer and consumer
Example fix
// before: worker deserializes a plan with a named UDF -> panic let lf: LazyFrame = bincode::deserialize(bytes)?; // after: register in every worker before deserialize set_named_serde_registry(Arc::new(WorkerUdfRegistry) as _); let lf: LazyFrame = bincode::deserialize(bytes)?;
Defensive patterns
Strategy: validation
Validate before calling
// every worker/subprocess calls this before deserializing expressions set_named_serde_registry(Arc::new(WorkerUdfRegistry) as _);
Try / catch
let expr = std::panic::catch_unwind(|| serde_json::from_str::<Expr>(s))
.map_err(|_| anyhow!("named UDF registry not set in this process"))?; Prevention
- Centralize registry setup in the process entrypoint
- Deserializing in tests? register there too
- Ship the registry installer with the plan format
When it happens
Trigger: Deserializing a serialized expression/plan containing a named anonymous function (e.g. a Python UDF serialized by name) in a fresh interpreter/process/subprocess that did not set the registry at startup.
Common situations: Multiprocessing or cluster workers receiving pickled/serialized lazy frames; long-lived daemons that deserialize plans created elsewhere; minimal embeddings and test binaries that skip the registry bootstrap.
Related errors
- NAMED EXPR REGISTRY NOT SET
- NAMED AGG NOT FOUND
- NAMED FUNCTION NOT FOUND
- not implemented
- not implemented
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/26d4e27753f3bf2f.
Report an issue: GitHub.