BoundaryML/baml · error · DatamodelError

Unknown function

Error message

Unknown function {}

What it means

When validating an application expression (function call), the function name is looked up in the scope's set of known function identifiers. If the called name is not in scope, the validator pushes 'Unknown function {}'.

Solutions

  1. Fix the function name spelling to match its definition
  2. Define the function being called in the same baml_src scope
  3. Use the correct builtin identifier if a builtin was intended
  4. Check that the callee is declared before/in scope where used

Example fix

// before
function main() {
  return sumrize(text) // typo
}
// after
function main() {
  return summarize(text)
}
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the callee is a known function before emitting the call
let known: HashSet<&str> = expr_fns.iter().map(|f| f.name.as_str()).collect();
if !known.contains(callee_name) {
    bail!("unknown function {}", callee_name);
}

Prevention

When it happens

Trigger: Calling a function inside a BAML expression function where the callee name is not a defined expression function, builtin, or other in-scope callable.

Common situations: Typos in function names, calling a function that is defined but not visible/imported, invoking a helper that was renamed or deleted, calling a non-builtin before it is declared.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/8468b2d8a110f0aa. Report an issue: GitHub.

Appendix: source

Thrown at engine/baml-lib/baml-core/src/validate/validation_pipeline/validations/expr_fns.rs:301

    }
}

fn validate_expression(ctx: &mut Context<'_>, expr: &Expression, scope: &HashSet<String>) {
    match &expr {
        Expression::Identifier(identifier) => {
            if !scope.contains(&identifier.to_string()) {
                ctx.push_error(DatamodelError::new_anyhow_error(
                    anyhow::anyhow!("Unknown variable {}", &identifier.to_string()),
                    identifier.span().clone(),
                ));
            }
        }
        Expression::Lambda(_args, _body, _span) => {}
        Expression::App(app) => {
            // Validate the function name.
            if !scope.contains(app.name.name()) {
                ctx.push_error(DatamodelError::new_anyhow_error(
                    anyhow::anyhow!("Unknown function {}", &app.name.to_string()),
                    app.span().clone(),
                ));
            }

            // Validate generics.
            if ir::builtin::is_builtin_identifier(app.name.name()) && app.type_args.is_empty() {
                ctx.push_error(DatamodelError::new_anyhow_error(
                    anyhow::anyhow!(
                        "Generic function {} must have a type argument. Try adding a type argument like this: {}<Type>",
                        app.name.name(),
                        app.name.name()
                    ),
                    app.span().clone(),
                ));
            }
            for arg in &app.args {
                validate_expression(ctx, arg, scope);
            }

View on GitHub (pinned to bd85ce9dee)