BoundaryML/baml · error

unsupported atom

Error message

unsupported atom: {value:#?}

What it means

Panic in expression codegen when an atom (literal) expression has a value kind the compiler does not know how to lower to bytecode. Only a fixed set of atom types (int, bool, float, string, null, etc.) is handled; the exhaustive match ends in a catch-all that panics with a debug dump of the value. This means the THIR contains an atom variant codegen was never taught to emit.

Solutions

  1. Identify the atom variant printed in the panic message and confirm whether your source expression can be rewritten to use only scalar literals
  2. Refactor the expression so the compound value is constructed via its proper expression form instead of appearing as an atom
  3. Upgrade/patch the compiler to add a codegen arm for the missing atom variant
  4. File an issue with the `{value:#?}` dump — this is an unhandled compiler case, not a source-level error
Defensive patterns

Strategy: try-catch

Validate before calling

// Only pass scalar literals where atoms are expected
fn is_supported_atom(v: &Value) -> bool {
    matches!(v, Value::Int(_) | Value::Float(_) | Value::String(_) | Value::Bool(_) | Value::Null)
}

Type guard

fn as_scalar_atom(v: &BamlValue) -> Option<&BamlValue> {
    match v { BamlValue::Int(_) | BamlValue::Float(_) | BamlValue::String(_) | BamlValue::Bool(_) | BamlValue::Null(_) => Some(v), _ => None }
}

Try / catch

match std::panic::catch_unwind(|| compiler.compile(src)) {
    Ok(out) => out,
    Err(_) => { eprintln!("compiler hit an unhandled atom kind; check literal forms in source"); std::process::exit(1); }
}

Prevention

When it happens

Trigger: Compiling an `Expr::Atom` whose `BamlValueWithMeta` payload is not one of the explicitly matched literal kinds — e.g. a compound value (map, class instance, media object) reached codegen as an atom.

Common situations: Newly added value kinds in the IR not yet handled in codegen; media or nested-struct values appearing where only scalars are expected; internal desugaring bugs that fail to expand compound atoms before codegen.

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/4ff70122a2930f2d. Report an issue: GitHub.

Appendix: source

Thrown at engine/baml-compiler/src/codegen.rs:1111

                BamlValueWithMeta::Bool(v, _) => {
                    let index = self.add_constant(Value::Bool(*v));
                    self.emit(Instruction::LoadConst(index));
                }

                BamlValueWithMeta::Int(v, _) => {
                    let index = self.add_constant(Value::Int(*v));
                    self.emit(Instruction::LoadConst(index));
                }

                BamlValueWithMeta::Float(v, _) => {
                    let index = self.add_constant(Value::Float(*v));
                    self.emit(Instruction::LoadConst(index));
                }

                BamlValueWithMeta::String(v, _) => self.emit_string_literal(v),

                _ => panic!("unsupported atom: {value:#?}"),
            },

            thir::Expr::Block(block, _) => self.compile_block(block),

            thir::Expr::ArrayAccess {
                base,
                index,
                meta: _,
            } => {
                // ArrayAccess compilation for loading elements
                //
                // Steps to compile array[index] or map[key]:
                // 1. Compile the base expression (array or map)
                // 2. Compile the index/key expression
                // 3. Determine the type from metadata (List or Map)
                // 4. Emit the appropriate load instruction:
                //    - LoadArrayElement for arrays (expects integer index)
                //    - LoadMapElement for maps (expects string key)

View on GitHub (pinned to bd85ce9dee)