databendlabs/databend · error
function id not found
Error message
function id not found
What it means
When converting a registry-backed expression node, FunctionCall expressions look up their function id in the FunctionRegistry (fn_registry.get(id)). This expect panics when the id is absent — the expression references a function that was never registered (or was registered under another id) in the registry used at expression-build time.
Solutions
- Ensure the same FunctionRegistry instance used to parse/build expressions is passed to as_expr.
- Verify all function ids referenced by the plan are registered before lowering (register missing builtins/aggregates).
- If plans are persisted across versions, re-plan or migrate them after a function rename/removal.
- Handle get(id) with a proper error (unknown function id <id>) instead of expect to surface the offending id.
Example fix
// before
let function = fn_registry.get(id).expect("function id not found");
// after
let function = fn_registry.get(id).ok_or_else(||
ErrorCode::UnknownFunction(format!("function id not found: {id}")))?; Defensive patterns
Strategy: try-catch
Validate before calling
if !fn_registry.contains(id) {
return Err(ErrorCode::UnknownFunction(format!("function id not found: {id}")));
} Try / catch
// prefer registry lookup returning Result
let function = match fn_registry.get(id) {
Some(f) => f,
None => return Err(ErrorCode::UnknownFunction(format!("unknown function id: {id}"))),
}; Prevention
- Use a single shared FunctionRegistry for parse and lowering
- Register all referenced functions before as_expr
- Migrate persisted plans after builtin renames
- Replace expect with a typed unknown-function error carrying the id
When it happens
Trigger: Calling as_expr(fn_registry) on an expression AST containing a FunctionCall whose id is not present in the supplied registry — e.g. a function removed/renamed between AST construction and lowering, or two different registry instances used.
Common situations: Version changes where builtin/aggregate functions were renamed or dropped while serialized plans or embedders (bendpy) reference old ids; registering functions into one registry but lowering expressions with another.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Addition resulted in NaN
- AggregateMeta does not support exchanging between multiple…
- binary literal is not supported
- Buffer pool working queue need unbounded.
- column view storage type mismatch
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/d0432fe306e25ae1.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/expression/src/expression.rs:1169
RemoteExpr::Cast {
span,
is_try,
expr,
dest_type,
} => Expr::Cast(Cast {
span: *span,
is_try: *is_try,
expr: Box::new(expr.as_expr(fn_registry)),
dest_type: dest_type.clone(),
}),
RemoteExpr::FunctionCall {
span,
id,
generics,
args,
return_type,
} => {
let function = fn_registry.get(id).expect("function id not found");
Expr::FunctionCall(FunctionCall {
span: *span,
id: id.clone(),
function,
generics: generics.clone(),
args: args.iter().map(|arg| arg.as_expr(fn_registry)).collect(),
return_type: return_type.clone(),
})
}
RemoteExpr::LambdaFunctionCall {
span,
name,
args,
lambda_expr,
lambda_display,
return_type,
} => Expr::LambdaFunctionCall(LambdaFunctionCall {
span: *span,View on GitHub (pinned to 288d84d76e)