BoundaryML/baml · critical

make_closure: lambda_idx {lambda_idx} out of range

Error message

make_closure: lambda_idx {lambda_idx} out of range

What it means

Panic in the MakeClosure emission helper: lambda_object_indices has no entry for the requested lambda_idx, so the emitter cannot find the pre-allocated closure object index. Every lambda that a function instantiates must have its object index allocated before the MakeClosure instruction is emitted. A missing entry means lambda allocation and emission are out of sync.

Source

Thrown at baml_language/crates/baml_compiler2_emit/src/emit.rs:3336

        });

        locals
    }

    /// Emit a `MakeClosure` bytecode instruction with the given counts.
    ///
    /// This is the underlying implementation called by both the `PullSink`
    /// trait methods (`make_closure` and `make_closure_with_type_args`).
    fn emit_make_closure_bytecode(
        &mut self,
        lambda_idx: usize,
        capture_count: usize,
        ntypeargs: usize,
    ) {
        let obj_idx = *self
            .lambda_object_indices
            .get(lambda_idx)
            .unwrap_or_else(|| panic!("make_closure: lambda_idx {lambda_idx} out of range"));
        let name = self
            .lambda_names
            .get(lambda_idx)
            .cloned()
            .unwrap_or_else(|| format!("<lambda {lambda_idx}>"));
        let inst = self.emit(Instruction::MakeClosure {
            obj_idx: ObjectIndex::from_raw(obj_idx),
            capture_count,
            ntypeargs,
        });
        self.set_operand(inst, OperandMeta::Object(name));
    }
}

impl<'ctx> PullSink<'ctx> for StackifyCodegen<'ctx, '_> {
    type Error = Infallible;

    fn pull_constant(&mut self, constant: &Constant<'ctx>) -> Result<(), Self::Error> {

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Ensure the lambda pre-pass allocates an object index for every lambda referenced by the function before emission.
  2. Check that lambda indices used at MakeClosure sites match the numbering produced during allocation.
  3. Reproduce with the BAML source containing the lambda and file a compiler bug.
  4. Pin to a compiler version without the lambda-numbering regression.
Defensive patterns

Strategy: validation

Validate before calling

// verify every lambda use site has a prior allocation
assert!(lambdas.iter().all(|l| lambda_object_indices.contains_key(&l.idx)));

Try / catch

// compiler panic — capture repro at the CLI boundary
match compile_project() {
    Err(Crash { ref input, .. }) => file_bug_report(input),
    Ok(_) => {}
}

Prevention

When it happens

Trigger: Emitting a closure-creation site for lambda_idx that was never registered in lambda_object_indices — e.g. the lambda pre-pass skipped or skipped-failed for that lambda but a use site still references it.

Common situations: Compiler development around lambda/closure handling; may surface when a lambda is only referenced (not defined) in the compiled function or after changes to lambda numbering.

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


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