BoundaryML/baml · critical
sys_op callee must resolve to a statically-known global func
Error message
sys_op callee must resolve to a statically-known global function: {callee:?} What it means
This is a compiler-internal panic raised while lowering a sys_op call in the baml_compiler2_emit backend. The emitter requires that the callee of a sys_op instruction resolve to a statically-known global function so it can emit a GlobalIndex; if the callee symbol cannot be mapped to a global index, the compiler treats it as a broken internal invariant and panics. It indicates the MIR passed to the emitter contains a call whose target was not registered as a global, which should have been caught in earlier passes.
Source
Thrown at baml_language/crates/baml_compiler2_emit/src/emit.rs:2538
Terminator::SysOp {
callee,
args,
runtime_id,
destination,
target,
unwind: _,
} => {
let callee_item = pull_semantics::resolve_constant_function_item(
callee,
&self.analysis.classifications,
&self.analysis.def_use,
);
let global_callee = callee_item
.as_ref()
.and_then(|item| self.try_function_global_index(item))
.map(GlobalIndex::from_raw)
.unwrap_or_else(|| {
panic!(
"sys_op callee must resolve to a statically-known global function: {callee:?}"
)
});
unwrap_infallible(pull_semantics::walk_call_direct_args(self, args));
if let Some(runtime_id) = runtime_id {
unwrap_infallible(pull_semantics::walk_operand_pull(self, runtime_id));
}
let inst = if runtime_id.is_some() {
self.emit(Instruction::SysOpWithRuntimeId(global_callee))
} else {
self.emit(Instruction::SysOp(global_callee))
};
if let Some(item) = &callee_item {
self.set_operand(inst, OperandMeta::Callable(item.to_string()));
}
self.emit_store_place(destination);
self.emit_jump_unless_fallthrough(*target);View on GitHub (pinned to bd85ce9dee)
Solutions
- Ensure the sys_op callee is a statically-known global function (a top-level fn) rather than a lambda, method value, or dynamic callee.
- Check that the front-end/MIR passes registered every called function in the globals map so try_function_global_index can resolve it.
- File a bug with the BAML source that reproduces it; this is a compiler invariant violation, not a user-fixable configuration issue.
- Bisect compiler/toolchain versions to find the regression and pin to a working baml-cli version.
Example fix
// before: calling a sys_op through a non-global callee let f = some.dynamic_callee; sys_op(f, args); // after: call the named global function directly sys_op(known_global_fn, args);
Defensive patterns
Strategy: validation
Validate before calling
// ensure sys_op callees are top-level named functions
fn is_static_global_callee(callee: &Callee) -> bool {
matches!(callee, Callee::NamedFunction(name) if registry.contains_global(name))
} Type guard
fn as_global_index(callee: &Callee) -> Option<GlobalIndex> {
match callee {
Callee::NamedFunction(name) => globals.get(name).map(|i| GlobalIndex::from_raw(*i)),
_ => None,
}
} Try / catch
// panics are not catchable; guard the pipeline
match compile(source) {
Ok(bytecode) => run(bytecode),
Err(e) => log_compiler_bug(e), // include repro source
} Prevention
- Call sys_ops only with statically-known global functions
- Keep compiler and runtime versions aligned
- Add CI compile tests for every sys_op usage pattern
- Fuzz the compiler front-end to catch unresolved callees early
When it happens
Trigger: Compiling BAML source where a sys_op call's callee item fails try_function_global_index(), e.g. the callee is a dynamically-dispatched or unregistered function reference rather than a top-level function definition.
Common situations: Encountered during BAML compiler development or when feeding IR from a modified/buggy front-end pass; end users hit it only when the compiler pipeline has a regression (e.g. a new language feature lowering calls differently).
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- exhaustive realized-leaf template classification
- interface index {} is not an Object::Interface
- interface `{}` declares no method `{}` for its default
- type-alias offset fits u32
- expected jump instruction at index {instruction_idx}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/9757e37b2f90a57b.
Report an issue: GitHub.