BoundaryML/baml · error
spread operator can only be used on classes at
Error message
spread operator can only be used on classes at {:?} What it means
In a ClassConstructor expression, the `..spread` syntax requires the spread operand to be a class instance. The interpreter's map-spread support is commented out (TODO), so spreading a map or any non-class value throws "spread operator can only be used on classes at {:?}".
Solutions
- Spread only actual class instances (e.g. another ClassName { ... } value)
- List fields explicitly instead of spreading a map: write out each field assignment
- If the source is a map, access its entries and assign them to fields individually
- Upgrade BAML and check whether map spreading has since been implemented
Example fix
// before
let c = User { ..user_map } // spread on map unsupported
// after
let c = User { name: user_map.name, age: user_map.age } Defensive patterns
Strategy: validation
Validate before calling
// Only allow class instances as spread sources
function assertSpreadable(v: unknown): void {
if (v === null || typeof v !== "object" || Array.isArray(v) || !isBamlClassInstance(v))
throw new Error("Spread requires a class instance");
} Type guard
function isBamlClassInstance(v: unknown): boolean {
return v !== null && typeof v === "object" && !Array.isArray(v) && (v as any).__baml_class === true;
} Try / catch
try {
return evalBaml(ctorExpr);
} catch (e) {
if (String(e).includes("spread operator can only be used on classes")) {
throw new Error("Expand map fields explicitly — spread supports class instances only");
}
throw e;
} Prevention
- Write fields explicitly when the source is a map
- Remember map spreading is unimplemented (TODO) in the interpreter
- Construct intermediate class instances if you need to merge structured data
- Check release notes before relying on newly proposed spread semantics
When it happens
Trigger: Writing `ClassName { ..other_value }` where other_value evaluates to a map, list, or scalar rather than an instance of a class.
Common situations: Trying to merge a map of fields into a class constructor (a common pattern in other languages) that BAML's interpreter does not support; passing the result of a parse that yielded a map instead of a class.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- arity mismatch: expected
- array access on non-list at
- array assignment index out of bounds
- array assignment on non-list value at
- array assignment requires a non-negative integer index at
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/849da5e342c986be.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-compiler/src/thir/interpret.rs:2105
run_llm_function,
watch_handler,
function_name,
)
.await?,
)?;
match spread_val.clone() {
BamlValueWithMeta::Class(_, spread_fields, _) => {
for (k, v) in spread_fields.iter() {
field_map.insert(k.clone(), v.clone());
}
}
// // TODO: Allow maps to be spread?
// BamlValueWithMeta::Map(spread_fields) => {
// for (k, v) in spread_fields.iter() {
// field_map.insert(k.clone(), v.clone());
// }
// }
_ => bail!(
"spread operator can only be used on classes at {:?}",
meta.0
),
}
}
}
}
EvalValue::Value(BamlValueWithMeta::Class(
name.clone(),
field_map,
meta.clone(),
))
}
Expr::Builtin(builtin, meta) => {
use crate::thir::Builtin;
match builtin {
Builtin::FetchValue => {View on GitHub (pinned to bd85ce9dee)