{"record":{"id":"da97f6933f9659c9","repo":"BoundaryML/baml","slug":"baml-json-serialize-returned-non-string-value-other","errorCode":null,"errorMessage":"baml.json.serialize returned non-string value: {other:?}","messagePattern":"baml\\.json\\.serialize returned non-string value: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baml_language/crates/baml_exec/src/output.rs","lineNumber":112,"sourceCode":"    value: BexExternalValue,\n    return_type: &RuntimeTy,\n    helper_context: &HelperCallContext,\n) -> Result<String> {\n    let result = engine\n        .call_function(\n            \"baml.json.serialize\",\n            vec![value],\n            helper_context.call_context(indexmap::IndexMap::from([(\n                \"T\".to_string(),\n                return_type.clone(),\n            )])),\n            true,\n        )\n        .await\n        .map_err(|e| anyhow!(\"baml.json.serialize failed: {e:?}\"))?;\n    match result {\n        BexExternalValue::String(s) => Ok(s.to_string()),\n        other => Err(anyhow!(\n            \"baml.json.serialize returned non-string value: {other:?}\"\n        )),\n    }\n}\n\n/// Human-readable formatting for `BexExternalValue`.\n///\n/// Thin wrapper over [`BexExternalValue::render_readable`] — the canonical\n/// structural renderer, shared with the engine's uncaught-throw rendering so\n/// `baml run` output and a leaked `throw` render identically.\npub fn format_value(value: &BexExternalValue) -> String {\n    value.render_readable()\n}\n","sourceCodeStart":94,"sourceCodeEnd":126,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/baml_exec/src/output.rs#L94-L126","documentation":"serialize_via_baml_json expects the `baml.json` function to return a BexExternalValue::String (the JSON text). If the call succeeds but yields any other external value variant, this error is raised. It is an internal contract violation: baml.json must produce a string representation, so a non-string result means the runtime returned something unexpected.","triggerScenarios":"baml.json evaluation completes successfully but the runtime returns a non-string BexExternalValue (e.g. an object/array/number variant) instead of the serialized JSON string.","commonSituations":"Runtime engine version where baml.json returns a structured value rather than a string; custom or overridden `baml.json` function returning a non-string; engine/stdlib mismatch after upgrading baml_language.","solutions":["Inspect `{other:?}` in the message to see which variant was returned","Ensure no user code overrides or wraps the `baml.json` function so it returns a string","Check engine/stdlib version alignment with baml_language (mismatch can change baml.json's return type)","File/fix an internal invariant issue in the runtime if stock baml.json returns non-string values"],"exampleFix":"// before\nother => Err(anyhow!(\"baml.json.serialize returned non-string value: {other:?}\"))\n// after\nother => Err(anyhow!(\"baml.json.serialize returned non-string value: {other:?}\"))\n// caller side: assert the function's return type is string before serializing","handlingStrategy":"type-guard","validationCode":"// ensure no user-defined override of baml.json and that engine/stdlib versions match\nassert_engine_matches_baml_language_version();","typeGuard":"fn is_string_value(v: &BexExternalValue) -> bool {\n    matches!(v, BexExternalValue::String(_))\n}","tryCatchPattern":"match serialize_via_baml_json(...).await {\n    Ok(s) => Ok(s),\n    Err(e) if e.to_string().contains(\"non-string value\") => {\n        // log variant and treat as internal invariant violation\n        Err(e.context(\"baml.json returned non-string; check engine/stdlib versions\"))\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Never override or wrap the built-in baml.json function so it returns non-string values","Keep runtime engine and stdlib versions in lockstep with baml_language","Add a regression test asserting baml.json returns a string for your output types"],"tags":["serialization","type-mismatch","runtime","baml"],"backgroundTag":"unexpected-response-shape","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}