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

  1. Declare the parameter as the class named in the error, or add it to the union: `ClassA | ClassB`
  2. Verify the caller constructs the correct class type (matching field names/types) as declared in .baml
  3. If structural typing was expected, ensure the class actually is a subtype in the IR (same name and compatible fields)
  4. 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

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


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/abe99f56ce39bf6a. Report an issue: GitHub.