{"record":{"id":"dcd331c2910cd546","repo":"BoundaryML/baml","slug":"could-not-unify-string-with","errorCode":null,"errorMessage":"Could not unify String with {:?}","messagePattern":"Could not unify String with (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-lib/baml-core/src/ir/ir_helpers/mod.rs","lineNumber":246,"sourceCode":"    /// and the type simultaneously, associating each node in the `BamlValue` with its\n    /// `FieldType`.\n    fn distribute_type_with_meta<T: Clone + std::fmt::Debug>(\n        &self,\n        value: BamlValueWithMeta<T>,\n        field_type: TypeIR,\n    ) -> anyhow::Result<BamlValueWithMeta<(T, TypeIR)>> {\n        match value {\n            BamlValueWithMeta::String(s, meta) => {\n                let literal_type =\n                    TypeIR::Literal(LiteralValue::String(s.clone()), Default::default());\n                let primitive_type = TypeIR::Primitive(TypeValue::String, Default::default());\n\n                if self.is_subtype(&literal_type, &field_type)\n                    || self.is_subtype(&primitive_type, &field_type)\n                {\n                    return Ok(BamlValueWithMeta::String(s, (meta, field_type)));\n                }\n                anyhow::bail!(\"Could not unify String with {:?}\", field_type)\n            }\n            BamlValueWithMeta::Int(i, meta)\n                if self.is_subtype(\n                    &TypeIR::Literal(LiteralValue::Int(i), Default::default()),\n                    &field_type,\n                ) =>\n            {\n                Ok(BamlValueWithMeta::Int(i, (meta, field_type)))\n            }\n            BamlValueWithMeta::Int(i, meta)\n                if self.is_subtype(\n                    &TypeIR::Primitive(TypeValue::Int, Default::default()),\n                    &field_type,\n                ) =>\n            {\n                Ok(BamlValueWithMeta::Int(i, (meta, field_type)))\n            }\n            BamlValueWithMeta::Int(_i, _meta) => {","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-lib/baml-core/src/ir/ir_helpers/mod.rs#L228-L264","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the .baml return type so the field's declared type matches the actual string value","Add or correct a literal type (e.g. @alias/literal string) if the field expects a literal","Adjust parsing/coercion logic so values are converted to the expected type before distribution","Regenerate clients after .baml type changes"],"exampleFix":"// before (.baml)\nclass A { count int }\n// value produced: \"42\" as string -> unify fails\n// after\nclass A { count string }\n// or coerce: Int(value) before distributing","handlingStrategy":"try-catch","validationCode":"// check value matches declared field type before distribution\nfn is_string_compatible(v: &str, t: &TypeIR) -> bool {\n  matches!(t, TypeIR::Primitive(TypeValue::String, _))\n    || matches!(t, TypeIR::Literal(LiteralValue::String(s), _) if s == v)\n}","typeGuard":"fn as_string_field(v: &BamlValue, t: &TypeIR) -> Option<&str> {\n  match (v, t) {\n    (BamlValue::String(s), _) => Some(s),\n    _ => None,\n  }\n}","tryCatchPattern":"match distribute_type(&value, &field_type) {\n  Ok(v) => v,\n  Err(e) if e.to_string().contains(\"Could not unify\") => {\n    // schema/value mismatch: fall back to string field or report schema violation\n    distribute_type(&BamlValue::String(value.to_string()), &string_type)?\n  }\n  Err(e) => return Err(e),\n}","preventionTips":["Declare .baml return types to match what the LLM actually emits","Add explicit casts/checks when coercing parsed output","Pin and test schemas against sample model outputs"],"tags":["baml","unification","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}