BoundaryML/baml · critical
undefined function: baml.deep_copy
Error message
undefined function: baml.deep_copy
What it means
Panic when emitting a deep-copy operation: the emitter unconditionally looks up the builtin global "baml.deep_copy" in the globals map and panics if it is absent. The compiler assumes the runtime pre-registers this builtin; if the builtin was never registered (or renamed), deep-copy call sites cannot be lowered.
Solutions
- Ensure the runtime prelude (which registers baml.deep_copy) is loaded before compiling/running.
- Upgrade or align compiler and runtime versions so the builtin name matches.
- Check for typos/renames of the builtin in a custom prelude.
- Report the missing-builtin scenario to the BAML maintainers if the prelude is stock.
Example fix
// before: embedding the VM without the builtin prelude let mut vm = Vm::new(); // after: register builtins first let mut vm = Vm::new(); vm.register_builtins(); // includes baml.deep_copy
Defensive patterns
Strategy: validation
Validate before calling
// check the builtin is registered before compiling deep-copy sites
if vm.globals().get("baml.deep_copy").is_none() {
vm.register_builtins();
} Type guard
fn has_deep_copy_builtin(globals: &HashMap<String, usize>) -> bool {
globals.contains_key("baml.deep_copy")
} Try / catch
// panics abort the process; validate environment beforehand
assert!(globals.contains_key("baml.deep_copy"), "runtime prelude not loaded"); Prevention
- Always initialize the runtime with the standard prelude/builtins
- Keep baml-cli and the embedded runtime on matching versions
- Grep for builtin renames when upgrading across versions
- Smoke-test deep-copy code paths after any runtime embedding change
When it happens
Trigger: Compiling code that performs a deep copy (e.g. deep-cloning a class/dynamic value) while the globals table lacks the "baml.deep_copy" builtin — typically because the runtime prelude wasn't loaded or the builtin was renamed across versions.
Common situations: Version mismatch between the compiler and runtime prelude, embedding the BAML runtime without registering builtins, or a renamed builtin after an upgrade.
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
- array access should be either map or array.
- baml.panics.Unreachable
- class field count fits u32
- class offset fits u32
- enum offset fits u32
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/4fa6502fdb3dfcc6.
Report an issue: GitHub.
Appendix: source
Thrown at baml_language/crates/baml_compiler2_emit/src/emit.rs:3489
fn alloc_uint8array(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
use std::fmt::Write;
// Store the byte data as a compile-time constant template, then deep-copy
// it to produce a mutable TLAB allocation (matching array literal semantics).
let mut display = String::from("b\"");
for b in bytes {
write!(display, "\\x{b:02x}").unwrap();
}
display.push('"');
let obj_idx = self.mint_object(Object::Uint8Array(bytes.to_vec().into()));
let idx = self.add_constant(ConstValue::Object(ObjectIndex::from_raw(obj_idx)));
let inst = self.emit(Instruction::LoadConst(idx));
self.set_operand(inst, OperandMeta::Const(display));
let deep_copy_idx = self
.globals
.get("baml.deep_copy")
.copied()
.unwrap_or_else(|| panic!("undefined function: baml.deep_copy"));
let inst = self.emit(Instruction::Call {
callee: GlobalIndex::from_raw(deep_copy_idx),
ntypeargs: 0,
});
self.set_operand(inst, OperandMeta::Callable("baml.deep_copy".to_string()));
Ok(())
}
fn alloc_map(
&mut self,
key_ty: &TyTemplate,
value_ty: &TyTemplate,
len: usize,
) -> Result<(), Self::Error> {
// Push key then value type on top of the entries; the VM's `AllocMap`
// pops value then key before processing the pairs.
self.load_type(key_ty)?;
self.load_type(value_ty)?;View on GitHub (pinned to bd85ce9dee)