BoundaryML/baml · error

Could not unify String with {:?}

Error message

Could not unify String with {:?}

What it means

distribute_type_with_meta annotates a BamlValue with its expected field type. For a string value, it first checks whether the value's literal type or its primitive (string) type is a subtype of the expected field_type; if not, unification fails with 'Could not unify String with {field_type:?}'. The value's shape and the schema disagree.

Source

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

    /// and the type simultaneously, associating each node in the `BamlValue` with its
    /// `FieldType`.
    fn distribute_type_with_meta<T: Clone + std::fmt::Debug>(
        &self,
        value: BamlValueWithMeta<T>,
        field_type: TypeIR,
    ) -> anyhow::Result<BamlValueWithMeta<(T, TypeIR)>> {
        match value {
            BamlValueWithMeta::String(s, meta) => {
                let literal_type =
                    TypeIR::Literal(LiteralValue::String(s.clone()), Default::default());
                let primitive_type = TypeIR::Primitive(TypeValue::String, Default::default());

                if self.is_subtype(&literal_type, &field_type)
                    || self.is_subtype(&primitive_type, &field_type)
                {
                    return Ok(BamlValueWithMeta::String(s, (meta, field_type)));
                }
                anyhow::bail!("Could not unify String with {:?}", field_type)
            }
            BamlValueWithMeta::Int(i, meta)
                if self.is_subtype(
                    &TypeIR::Literal(LiteralValue::Int(i), Default::default()),
                    &field_type,
                ) =>
            {
                Ok(BamlValueWithMeta::Int(i, (meta, field_type)))
            }
            BamlValueWithMeta::Int(i, meta)
                if self.is_subtype(
                    &TypeIR::Primitive(TypeValue::Int, Default::default()),
                    &field_type,
                ) =>
            {
                Ok(BamlValueWithMeta::Int(i, (meta, field_type)))
            }
            BamlValueWithMeta::Int(_i, _meta) => {

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Fix the .baml return type so the field's declared type matches the actual string value
  2. Add or correct a literal type (e.g. @alias/literal string) if the field expects a literal
  3. Adjust parsing/coercion logic so values are converted to the expected type before distribution
  4. Regenerate clients after .baml type changes

Example fix

// before (.baml)
class A { count int }
// value produced: "42" as string -> unify fails
// after
class A { count string }
// or coerce: Int(value) before distributing
Defensive patterns

Strategy: try-catch

Validate before calling

// check value matches declared field type before distribution
fn is_string_compatible(v: &str, t: &TypeIR) -> bool {
  matches!(t, TypeIR::Primitive(TypeValue::String, _))
    || matches!(t, TypeIR::Literal(LiteralValue::String(s), _) if s == v)
}

Type guard

fn as_string_field(v: &BamlValue, t: &TypeIR) -> Option<&str> {
  match (v, t) {
    (BamlValue::String(s), _) => Some(s),
    _ => None,
  }
}

Try / catch

match distribute_type(&value, &field_type) {
  Ok(v) => v,
  Err(e) if e.to_string().contains("Could not unify") => {
    // schema/value mismatch: fall back to string field or report schema violation
    distribute_type(&BamlValue::String(value.to_string()), &string_type)?
  }
  Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling distribute_type / distribute_type_with_meta on a BamlValueWithMeta::String whose expected TypeIR is not string and not a matching literal — e.g. coerced/parsed output typed as string being distributed into an int/bool/class field.

Common situations: LLM returned a value that doesn't match the declared .baml return type; schema/type changes after prompt output drifted; misaligned partial-parsing coercion results.

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