BoundaryML/baml · error

function ` ` not found while building control-flow…

Error message

function `{}` not found while building control-flow visualization

What it means

ControlFlowVisualization::build_from_hir searches the HIR's llm_functions for the requested function name and errors if none matches. This is a lookup failure while constructing a control-flow graph for a function: the name given does not correspond to any LLM function known to the compiler/HIR at that point.

Solutions

  1. Verify the function name exactly matches a function declared in the .baml source (check spelling and case).
  2. Ensure the function is an LLM function, not just an expr function, test, or helper — only llm_functions are visualized.
  3. Fix compile errors first so the HIR contains all functions, then retry the visualization.
  4. List available functions from the HIR and pick a valid name before calling build_from_hir.

Example fix

// before
ControlFlowVisualization::build_from_hir(&hir, "ExtractResume")?;
// after
let name = "ExtractResume";
if !hir.llm_functions.iter().any(|f| f.name == name) {
    return Err(anyhow!("function `{}` not found in BAML file", name));
}
ControlFlowVisualization::build_from_hir(&hir, name)?;
Defensive patterns

Strategy: validation

Validate before calling

pub fn ensure_function_exists(hir: &IntermediateRepr, name: &str) -> anyhow::Result<()> {
    if hir.llm_functions.iter().any(|f| f.name == name) {
        Ok(())
    } else {
        Err(anyhow::anyhow!(
            "function `{}` not found; available: {:?}",
            name,
            hir.llm_functions.iter().map(|f| f.name.clone()).collect::<Vec<_>>()
        ))
    }
}

Type guard

fn has_llm_function(hir: &IntermediateRepr, name: &str) -> bool {
    hir.llm_functions.iter().any(|f| f.name == name)
}

Try / catch

match ControlFlowVisualization::build_from_hir(&hir, fn_name) {
    Ok(viz) => viz,
    Err(e) if e.to_string().contains("not found while building control-flow") => {
        eprintln!("Unknown function `{}` — check spelling or recompile", fn_name);
        Default::default()
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling build_from_hir (directly or via function_graph_v2 tooling/tests like builds_simple_expr_function or missing_function_errors) with a function_name that is not present in hir.llm_functions — e.g. a typo, a deleted function, or a name only present as a non-LLM (expr function/test) symbol.

Common situations: IDE visualization or tooling referencing a function that was renamed or removed; analyzing a .baml file where the function is declared with different casing; asking for a graph before the HIR finished collecting LLM functions due to earlier compile errors.

Related errors


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

Appendix: source

Thrown at engine/baml-runtime/src/control_flow.rs:327

        }
    }
}

pub enum HirFunctionRef<'hir> {
    Expr(&'hir hir::ExprFunction),
    Llm(&'hir hir::LlmFunction),
}

pub fn build_from_hir(hir: &hir::Hir, function_name: &str) -> Result<ControlFlowVisualization> {
    if let Some(func) = hir.expr_functions.iter().find(|f| f.name == function_name) {
        return Ok(build_function_graph(HirFunctionRef::Expr(func)));
    }

    if let Some(func) = hir.llm_functions.iter().find(|f| f.name == function_name) {
        return Ok(build_function_graph(HirFunctionRef::Llm(func)));
    }

    Err(anyhow!(
        "function `{}` not found while building control-flow visualization",
        function_name
    ))
}

pub fn build_function_graph(function: HirFunctionRef<'_>) -> ControlFlowVisualization {
    match function {
        HirFunctionRef::Expr(func) => build_expr_function_graph(func),
        HirFunctionRef::Llm(func) => build_llm_function_graph(func),
    }
}

fn build_expr_function_graph(func: &hir::ExprFunction) -> ControlFlowVisualization {
    let mut ctx = HirTraversalContext::new(func.name.as_str(), func.span.clone());
    ctx.visit_function_body(&func.body);
    ctx.finish()
}

View on GitHub (pinned to bd85ce9dee)