BoundaryML/baml · error
interface body has no Pass-1 slot: {item}
Error message
interface body has no Pass-1 slot: {item} What it means
During the emit pass, an interface-machinery body (`ItemRef::InterfaceBody`) must already have a global slot assigned in Pass 1, recorded in `interface_body_slots` keyed by the body's declaration. This panic means the slot map has no entry for that declaration. Per the code comments, Pass 1 is supposed to slot every interface body declaration the compiler database sees, so a miss is an internal invariant violation, not user error.
Source
Thrown at baml_language/crates/baml_compiler2_emit/src/emit.rs:2043
/// Pass-1 global slot for a function item.
///
/// An interface-machinery body resolves by its DECLARATION
/// ([`baml_compiler2_mir::InterfaceBodyRef::decl`]) through [`Self::interface_body_slots`] —
/// its rendered spelling is display-only and keys nothing. Every other
/// item resolves by its rendered name through [`Self::globals`]; `None`
/// there means the callee is not statically addressable (the caller falls
/// back to an indirect call). A body missing its slot is an internal
/// error: `ItemRef::InterfaceBody` only exists for declarations this database
/// sees, and Pass 1 slots every one of them.
fn try_function_global_index(
&mut self,
item: &baml_compiler2_mir::ItemRef<'ctx>,
) -> Option<usize> {
if let baml_compiler2_mir::ItemRef::InterfaceBody(body) = item {
let slot = *self
.interface_body_slots
.get(&body.decl)
.unwrap_or_else(|| panic!("interface body has no Pass-1 slot: {item}"));
// The body's rendered spelling is display-only for resolution, but
// its last segment (the method name) is exactly what the declaring
// file's `defined_names` produces — the incremental edge grain.
self.references.record(&item.to_string());
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,View on GitHub (pinned to bd85ce9dee)
Solutions
- Run a clean (non-incremental) compile to confirm it is a stale-incremental-state issue, then clear the incremental cache
- Check that the interface declaration was present when Pass 1 assigned `interface_body_slots`; compare the Pass-1 declaration set against the emitting set
- If you just added a method to an interface, rebuild the whole package rather than relying on incremental output
- Report a compiler bug with the BAML source and the item text from the panic message
Example fix
// before (opaque panic on stale incremental state) $ baml build // after (force full rebuild) $ baml clean && baml build
Defensive patterns
Strategy: validation
Validate before calling
// before compiling, assert every InterfaceBody declaration has a Pass-1 slot
for item in all_items {
if let ItemRef::InterfaceBody(body) = item {
assert!(interface_body_slots.contains_key(&body.decl), "unslotted interface body: {item}");
}
} Try / catch
// run compilation in a worker and surface panics as diagnostics
match std::panic::catch_unwind(|| compile(inputs)) {
Ok(out) => out,
Err(_) => diagnose_and_rebuild_from_scratch(),
} Prevention
- Clear incremental caches whenever interface definitions change
- Prefer full rebuilds when adding methods to interfaces
- Keep Pass 1 and emit consuming the same declaration snapshot
- File a bug with repro source if a clean rebuild still panics
When it happens
Trigger: Emitting code that references an interface method body when `interface_body_slots` was populated in Pass 1 without that declaration — e.g. the declaration was added after Pass 1 ran (incremental recompile that added a new interface method), a cross-package/cross-file interface whose body was never slotted, or a stale compiler database after an edit.
Common situations: Incremental compilation after editing an interface to add methods; compiler caching keyed incorrectly so a fresh declaration skipped Pass 1; parallel emit workers seeing a declaration set that differs from the Pass-1 serial run.
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
- type_arg_templates count fits in u16
- ntypeargs fits in u16
- {what}: {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/0c00f3a18197f162.
Report an issue: GitHub.