{"record":{"id":"177537cb640d7007","repo":"BoundaryML/baml","slug":"make-closure-lambda-idx-lambda-idx-out-of-range","errorCode":null,"errorMessage":"make_closure: lambda_idx {lambda_idx} out of range","messagePattern":"make_closure: lambda_idx (.+?) out of range","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"baml_language/crates/baml_compiler2_emit/src/emit.rs","lineNumber":3336,"sourceCode":"        });\n\n        locals\n    }\n\n    /// Emit a `MakeClosure` bytecode instruction with the given counts.\n    ///\n    /// This is the underlying implementation called by both the `PullSink`\n    /// trait methods (`make_closure` and `make_closure_with_type_args`).\n    fn emit_make_closure_bytecode(\n        &mut self,\n        lambda_idx: usize,\n        capture_count: usize,\n        ntypeargs: usize,\n    ) {\n        let obj_idx = *self\n            .lambda_object_indices\n            .get(lambda_idx)\n            .unwrap_or_else(|| panic!(\"make_closure: lambda_idx {lambda_idx} out of range\"));\n        let name = self\n            .lambda_names\n            .get(lambda_idx)\n            .cloned()\n            .unwrap_or_else(|| format!(\"<lambda {lambda_idx}>\"));\n        let inst = self.emit(Instruction::MakeClosure {\n            obj_idx: ObjectIndex::from_raw(obj_idx),\n            capture_count,\n            ntypeargs,\n        });\n        self.set_operand(inst, OperandMeta::Object(name));\n    }\n}\n\nimpl<'ctx> PullSink<'ctx> for StackifyCodegen<'ctx, '_> {\n    type Error = Infallible;\n\n    fn pull_constant(&mut self, constant: &Constant<'ctx>) -> Result<(), Self::Error> {","sourceCodeStart":3318,"sourceCodeEnd":3354,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/baml_compiler2_emit/src/emit.rs#L3318-L3354","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the lambda pre-pass allocates an object index for every lambda referenced by the function before emission.","Check that lambda indices used at MakeClosure sites match the numbering produced during allocation.","Reproduce with the BAML source containing the lambda and file a compiler bug.","Pin to a compiler version without the lambda-numbering regression."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// verify every lambda use site has a prior allocation\nassert!(lambdas.iter().all(|l| lambda_object_indices.contains_key(&l.idx)));","typeGuard":null,"tryCatchPattern":"// compiler panic — capture repro at the CLI boundary\nmatch compile_project() {\n    Err(Crash { ref input, .. }) => file_bug_report(input),\n    Ok(_) => {}\n}","preventionTips":["Allocate object indices for all lambdas in a pre-pass before emission","Keep lambda numbering consistent between allocation and use sites","Test closures/lambdas in CI compile snapshots","Report compiler crashes with a minimal BAML repro"],"tags":["compiler","closures","bytecode","panic"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}