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

  1. Ensure the same FunctionRegistry instance used to parse/build expressions is passed to as_expr.
  2. Verify all function ids referenced by the plan are registered before lowering (register missing builtins/aggregates).
  3. If plans are persisted across versions, re-plan or migrate them after a function rename/removal.
  4. 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

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


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)