databendlabs/databend · error
function factory must be set before registering
Error message
function factory must be set before registering
What it means
This panic occurs in `FunctionRegistryBuilder::register` when the builder's optional `factory` field is `None`. The function factory must be installed (via the builder's factory-setting API) before `register` is called, because registration delegates function resolution to the factory. The library intentionally panics via `expect` since this is a programmer/API-usage error, not a runtime condition.
Solutions
- Set the function factory on the builder before calling `register` (e.g. assign the `factory` field or call the builder's factory-setting method).
- Prefer the existing function-registration macros/helpers in the crate, which wire the factory automatically.
- Audit custom builder construction paths for `..Default::default()` that silently reset `factory` to None.
Example fix
// before
let builder = FunctionRegistryBuilder { name, ..Default::default() };
builder.register(registry);
// after
let builder = FunctionRegistryBuilder { name, factory: Some(Box::new(MyFactory)), ..Default::default() };
builder.register(registry); Defensive patterns
Strategy: type-guard
Validate before calling
assert!(builder.factory.is_some(), "factory must be set before register");
Type guard
fn factory_is_set(b: &FunctionRegistryBuilder) -> bool { b.factory.is_some() } Try / catch
// Rust panics are not catchable idiomaticly here; guard instead:
if !factory_is_set(&builder) { return Err(ErrorCode::Internal("factory not set")); } Prevention
- Always construct registry builders through the provided macros/helpers.
- Avoid `..Default::default()` struct-update syntax that can reset required fields.
- Add a debug_assert for factory presence in custom registration paths.
When it happens
Trigger: Calling `FunctionRegistryBuilder::register(name, ...)` on a builder that was never given a function factory — i.e., skipping the factory assignment step (e.g. `with_factory` / the `factory` builder field) before calling `register`.
Common situations: Hand-rolling a registry builder instead of using the standard helper macros; refactoring that moves or deletes the factory setup call; constructing a builder with struct-update syntax (`..Default::default()`) that leaves `factory` as None.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- typed builder must produce exactly one function
- typed calc_domain must be specified
- Unsupported format for
- Unsupported source type. Expected path, pandas.DataFrame…
- Access denied: is outside allowed directories
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/e238f6b5d4ce185c.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/expression/src/function/function_builder.rs:238
})
.map(|builder| Arc::new(builder.finish()))
})));
self
}
pub fn register(self) -> &'a mut FunctionRegistry {
let FunctionBuilder {
registry,
name,
property,
aliases,
additional_cast_rules,
dynamic_cast_rules,
factory,
..
} = self;
let factory = factory.expect("function factory must be set before registering");
registry.register_function_factory(&name, factory);
Self::register_common(
registry,
&name,
property,
aliases,
additional_cast_rules,
dynamic_cast_rules,
);
registry
}
}
pub struct InlineFunctionBuilder {
name: String,View on GitHub (pinned to 288d84d76e)