BoundaryML/baml · error · anyhow::Error
Could not unify Class {} with {:?}
Error message
Could not unify Class {} with {:?} What it means
A Class value's type could not be unified with the expected TypeIR: `is_subtype(class_type, field_type)` returned false in distribute_type_with_meta, so the pass refuses to attach the type. The expected type must be the same class (or a supertype/alias/union that admits it).
Source
Thrown at engine/baml-lib/baml-core/src/ir/ir_helpers/mod.rs:353
BamlValueWithMeta::Enum(name, val, meta) => {
if self.is_subtype(
&TypeIR::Enum {
name: name.clone(),
dynamic: false,
meta: Default::default(),
},
&field_type,
) {
Ok(BamlValueWithMeta::Enum(name, val, (meta, field_type)))
} else {
anyhow::bail!("Could not unify Enum {} with {:?}", name, field_type)
}
}
BamlValueWithMeta::Class(name, fields, meta) => {
if !self.is_subtype(&TypeIR::class(name.as_str()), &field_type) {
anyhow::bail!("Could not unify Class {} with {:?}", name, field_type);
} else {
let class_fields = self.class_fields(&name)?;
let mapped_fields = fields
.into_iter()
.map(|(k, v)| {
let field_type = match class_fields.get(k.as_str()) {
Some(ft) => ft.clone(),
None => infer_type_with_meta(&v).unwrap_or(UNIT_TYPE.clone()),
};
let mapped_field = self.distribute_type_with_meta(v, field_type)?;
Ok((k, mapped_field))
})
.collect::<anyhow::Result<BamlMap<String, BamlValueWithMeta<(T, TypeIR)>>>>(
)?;
Ok(BamlValueWithMeta::Class(
name,
mapped_fields,
(meta, field_type),View on GitHub (pinned to bd85ce9dee)
Solutions
- Declare the parameter as the class named in the error, or add it to the union: `ClassA | ClassB`
- Verify the caller constructs the correct class type (matching field names/types) as declared in .baml
- If structural typing was expected, ensure the class actually is a subtype in the IR (same name and compatible fields)
- Regenerate client types after .baml changes so stale SDK classes are not sent
Example fix
// before (.baml)
class Address { city string }
function Ship(dest: Person) -> bool { ... }
// caller sends an Address
// after (.baml)
function Ship(dest: Address) -> bool { ... } Defensive patterns
Strategy: validation
Validate before calling
function validateClassArg(className: string, declaredType: string): boolean {
return declaredType === className || declaredType.split('|').map(s => s.trim()).includes(className);
} Type guard
const isInstanceOf = <T extends object>(v: unknown, ctor: new (...a: never[]) => T): v is T => v instanceof ctor;
Prevention
- Construct arguments with generated client class types
- Regenerate SDKs after class renames/refactors
- Ensure unions in .baml include every concrete class you may send
- Add integration tests that call each function with realistic arguments
When it happens
Trigger: distribute_type over BamlValueWithMeta::Class(name, ..) when field_type is a different class, a primitive, a map, or a union excluding this class — usually during argument checking against .baml function signatures.
Common situations: Passing an instance of class A where class B is declared after a refactor; sending a raw object/dict where a class parameter is declared (or the reverse); unions that don't include the concrete class being sent.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Could not unify Float with {:?}
- Could not unify Bool with {:?}
- Could not unify map with {field_type:?}
- Could not infer child type
- Could not unify Media with {:?}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/abe99f56ce39bf6a.
Report an issue: GitHub.