BoundaryML/baml · error · anyhow::Error

Could not unify map with {field_type:?}

Error message

Could not unify map with {field_type:?}

What it means

While distributing types over a Map value, BAML calls `map_types` to extract the key/value types of the expected TypeIR. If the expected type is not a `map<K, V>` (e.g. a primitive, class, or list), no key/value pair can be extracted and this error is thrown.

Source

Thrown at engine/baml-lib/baml-core/src/ir/ir_helpers/mod.rs:297

            BamlValueWithMeta::Bool(b, meta) => {
                let literal_type = TypeIR::Literal(LiteralValue::Bool(b), Default::default());
                let primitive_type = TypeIR::Primitive(TypeValue::Bool, Default::default());

                if self.is_subtype(&literal_type, &field_type)
                    || self.is_subtype(&primitive_type, &field_type)
                {
                    Ok(BamlValueWithMeta::Bool(b, (meta, field_type)))
                } else {
                    anyhow::bail!("Could not unify Bool with {:?}", field_type)
                }
            }

            BamlValueWithMeta::Null(meta) => Ok(BamlValueWithMeta::Null((meta, field_type))),

            BamlValueWithMeta::Map(pairs, meta) => {
                let (annotation_key_type, annotation_value_type) = map_types(self, &field_type)
                    .ok_or(anyhow::anyhow!("Could not unify map with {field_type:?}"))?;

                let mapped_fields: BamlMap<String, BamlValueWithMeta<(T, TypeIR)>> = pairs
                    .into_iter()
                    .map(|(key, val)| {
                        let sub_value =
                            self.distribute_type_with_meta(val, annotation_value_type.clone())?;

                        Ok((key, sub_value))
                    })
                    .collect::<anyhow::Result<BamlMap<String, BamlValueWithMeta<(T, TypeIR)>>>>()?;

                Ok(BamlValueWithMeta::Map(mapped_fields, (meta, field_type)))
            }

            BamlValueWithMeta::List(items, meta) => {
                let new_items = items
                    .into_iter()
                    .map(|i| {

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Declare the parameter/field as `map<string, T>` (with the element type you actually pass) in the .baml schema
  2. If the value is structured, define a class in .baml and pass it where a class type is expected, instead of a raw map
  3. Unwrap or replace optionals/unions so that map_types can resolve — `map<string,int>?` should still resolve, but a bare `string` will not
  4. Inspect the `field_type` debug-printed in the message to see which declared type was expected and align the payload

Example fix

// before (.baml)
function Upsert(data: string) -> bool { ... }
// caller sends data: {"a": 1}

// after (.baml)
function Upsert(data: map<string, int>) -> bool { ... }
Defensive patterns

Strategy: validation

Validate before calling

function validateMapArg(value: object, declaredType: string): boolean {
  return /^map\s*<\s*string/.test(declaredType) && value !== null && !Array.isArray(value);
}

Type guard

const isPlainObject = (v: unknown): v is Record<string, unknown> =>
  typeof v === 'object' && v !== null && !Array.isArray(v);

Prevention

When it happens

Trigger: distribute_type_with_meta on BamlValueWithMeta::Map when field_type is not a map type — e.g. declaring a parameter as `string` but the caller passes an object; or an alias resolving to a non-map type.

Common situations: Sending a JSON object for a parameter declared as a scalar; a class instance passed where a free-form `map<string, X>` was intended (or vice versa); type-alias refactors that changed a map into a class.

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