BoundaryML/baml · error
{what}: {item}
Error message
{what}: {item} What it means
`function_global_index` is the panicking wrapper around `try_function_global_index`: when a function item does not resolve to a Pass-1 global slot (it is missing from the `globals` map by its rendered name), the compiler aborts with the caller-supplied `what` context (e.g. "undefined function"). The code documents that a `None` from `try_function_global_index` normally means the callee is not statically addressable and callers should fall back to an indirect call; this wrapper is used on paths where resolution is required.
Source
Thrown at baml_language/crates/baml_compiler2_emit/src/emit.rs:2066
return Some(slot);
}
let rendered = item.to_string();
let slot = self.globals.get(&rendered).copied();
if slot.is_some() {
self.references.record(&rendered);
}
slot
}
/// [`Self::try_function_global_index`], panicking with `what` when the
/// item does not resolve.
fn function_global_index(
&mut self,
item: &baml_compiler2_mir::ItemRef<'ctx>,
what: &str,
) -> usize {
self.try_function_global_index(item)
.unwrap_or_else(|| panic!("{what}: {item}"))
}
/// Push a function reference as a value: a pooled, interned
/// `Object::GenericFunction` wrapper over the function's global slot
/// (empty `type_args` for a plain reference). Interning by
/// (function, `type_args`) over the shared object pool makes identical
/// references share ONE pooled object → pointer-stable identity
/// (`greet === greet`, `foo<int> === foo<int>`).
///
/// Serial emit scans the whole program pool here, so wrappers minted by
/// EARLIER functions are reused too. Parallel emit scans only this
/// worker's fragment; the serial merge replays the cross-function dedup
/// in original function order (see `merge_function_fragment`),
/// reproducing the exact serial candidate set and pool layout.
fn emit_pooled_function_value(
&mut self,
item: &baml_compiler2_mir::ItemRef<'ctx>,
type_args: &[baml_type::RealizedTy],View on GitHub (pinned to bd85ce9dee)
Solutions
- Verify the referenced function exists and is part of the compiled package set; add the missing package/module to the compilation
- Clean incremental caches and rebuild so Pass 1 re-slots all current functions
- Check whether the function was renamed; update the reference at the BAML source level
- If the callee can legitimately be unresolvable, switch the call site to the indirect-call fallback via `try_function_global_index` instead of the panicking wrapper
Example fix
// before
let global_idx = self.function_global_index(item, "undefined function");
// after
match self.try_function_global_index(item) {
Some(global_idx) => { /* direct reference */ }
None => { /* fall back to indirect call */ }
} Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: confirm every referenced function resolves in this compilation unit
let unresolved: Vec<_> = referenced_functions
.iter()
.filter(|f| !globals.contains_key(&f.to_string()))
.collect();
if !unresolved.is_empty() {
return Err(format!("unresolved functions: {:?}", unresolved));
} Try / catch
match std::panic::catch_unwind(|| emit_function(item)) {
Ok(_) => /* direct emit */,
Err(_) => /* fall back to indirect call via try_function_global_index */,
} Prevention
- Keep all referenced packages in the compilation unit
- Rebuild from scratch after renaming or moving functions
- Verify cross-package exports before referencing remote functions
- Use try_function_global_index with a fallback on non-critical paths
When it happens
Trigger: Emitting a function value or direct call to a function name absent from the `globals` slot map — e.g. calling a function defined in a package not registered in this compilation context, referencing a function that was deleted/renamed while stale incremental state persists, or a `Constant::Function`/`GenericFunction` whose item was never slotted by Pass 1.
Common situations: Cross-package BAML references to functions that aren't compiled into the current unit; renamed functions with stale caches; typos at the MIR level after a refactor of the function-name rendering (`ItemRef::to_string`) so the lookup key no longer matches the Pass-1 key.
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
- type_arg_templates count fits in u16
- ntypeargs fits in u16
- interface body has no Pass-1 slot: {item}
- undefined global item: {name_str}
- undefined variant: {enum_name_str}.{variant_str}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/9c3baeac5d726827.
Report an issue: GitHub.