{"record":{"id":"a7dbfd761ac28027","repo":"BoundaryML/baml","slug":"failed-to-coerce-value","errorCode":null,"errorMessage":"Failed to coerce value: {:?}","messagePattern":"Failed to coerce value: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-lib/jsonish/src/lib.rs","lineNumber":267,"sourceCode":"        of,\n        if raw_string_is_done {\n            baml_types::StreamingMode::NonStreaming\n        } else {\n            baml_types::StreamingMode::Streaming\n        },\n    );\n\n    // Determine the best way to get the desired schema from the parsed schema.\n\n    // Lets try to now coerce the value into the expected schema.\n    let parsed_value: BamlValueWithFlags = match target.coerce(&ctx, target, Some(&value)) {\n        Ok(v) => {\n            if v.conditions()\n                .flags()\n                .iter()\n                .any(|f| matches!(f, Flag::InferedObject(jsonish::Value::String(_, _))))\n            {\n                anyhow::bail!(\"Failed to coerce value: {:?}\", v.conditions().flags());\n            }\n\n            Ok::<BamlValueWithFlags, anyhow::Error>(v)\n        }\n        Err(e) => anyhow::bail!(\"Failed to coerce value: {:?}\", e),\n    }?;\n\n    log::debug!(\"Parsed JSONish (step 2 of parsing): {parsed_value:#?}\");\n\n    // let value: BamlValue = parsed_value.clone().into();\n    // println!(\"from_str value: {value}\");\n    // println!(\"-------------------------------------------------\");\n    // parsed_value.clear_flags();\n\n    Ok(parsed_value)\n}\n\nimpl ResponseBamlValue {","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-lib/jsonish/src/lib.rs#L249-L285","documentation":"In jsonish::from_str, after coercing the parsed value to the target type, the code checks the coercion flags: if the only evidence was an 'InferedObject' over a plain String (the parser guessed an object from a bare string), it refuses the result with 'Failed to coerce value'. This prevents accepting a string that was silently reinterpreted as the requested object type.","triggerScenarios":"from_str(&target_type, s) where the raw text is just a quoted/unquoted string but the target type is a class/object — the coercion produced an inferred object from a string flag.","commonSituations":"LLM returned a single value (e.g. a name or URL) where the schema expects an object; type changed in the BAML schema but the model output didn't.","solutions":["Make the prompt demand the full object shape with required fields","Check the target type — if a scalar is acceptable, use a string/class field type instead","Inspect the printed flags in the error to confirm the inferred-object coercion","Retry the generation or fall back to manual parsing for this response"],"exampleFix":"// schema\n// before: class Output { value string }\n// model returned: \"just a string\"\n// after: prompt: 'Respond with JSON: {\"value\": \"...\"}'","handlingStrategy":"validation","validationCode":"fn is_scalar_only(s: &str) -> bool { let t = s.trim().trim_matches(|c| c == '`'); !(t.starts_with('{') || t.starts_with('[')) }","typeGuard":null,"tryCatchPattern":"match jsonish::from_str(&object_type, out) {\n    Err(e) if e.to_string().contains(\"Failed to coerce value\") => {\n        // schema expects an object but model returned a scalar\n        retry_with_schema_example()\n    }\n    other => other,\n}","preventionTips":["Show the exact object schema in the prompt","If a scalar is valid, type the field as string not class","Feed one example output so the model mirrors the shape"],"tags":["type-coercion","json","schema"],"backgroundTag":"type-mismatch","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}