{"record":{"id":"26f92635eb0a2a44","repo":"BoundaryML/baml","slug":"failed-to-parse-json-entry","errorCode":null,"errorMessage":"Failed to parse JSON","messagePattern":"Failed to parse JSON","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-lib/jsonish/src/jsonish/parser/entry.rs","lineNumber":237,"sourceCode":"            }\n            Err(e) => {\n                log::debug!(\"Error fixing json: {e:?}\");\n            }\n        }\n    }\n\n    if options.allow_as_string {\n        return Ok(Value::String(\n            str.to_string(),\n            if is_done {\n                CompletionState::Complete\n            } else {\n                CompletionState::Incomplete\n            },\n        ));\n    }\n\n    Err(anyhow::anyhow!(\"Failed to parse JSON\"))\n}\n\npub fn parse(str: &str, options: ParseOptions, is_done: bool) -> Result<Value> {\n    let res = parse_func(str, options, is_done)?;\n    Ok(res.simplify(is_done))\n}\n\n#[cfg(test)]\nmod tests {\n    use baml_types::CompletionState;\n\n    use super::*;\n    use crate::jsonish::Value;\n\n    fn to_any_of(inner: Value, s: &str) -> Value {\n        Value::AnyOf(vec![inner], s.to_string())\n    }\n","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-lib/jsonish/src/jsonish/parser/entry.rs#L219-L255","documentation":"parse_func tries serde_json first, then a series of fallback/fixed parsers, and if every strategy fails to produce a Value it returns a generic 'Failed to parse JSON'. It is the terminal failure of the whole jsonish parsing pipeline for the given string.","triggerScenarios":"Passing a string to jsonish parse (or from_str) that neither serde_json nor any repair heuristic (fixing parser, markdown, multi-json, custom deserializers) can turn into a Value.","commonSituations":"LLM returned free-form prose with no JSON at all, an empty response, or output so malformed that even partial-repair strategies fail.","solutions":["Log the raw input string and confirm it actually contains JSON-like content","Check log::debug output ('Parsing: ...') to see which strategies were attempted","Retry the generation with an explicit JSON schema/format instruction","Add custom deserializers or use a markdown/code-fence wrapper so the content reaches the right parser","Handle the Err branch with a user-facing retry instead of panicking"],"exampleFix":"// before\nlet v = jsonish::from_str(&target, llm_output)?;\n// after\nlet v = match jsonish::from_str(&target, llm_output) {\n    Ok(v) => v,\n    Err(e) => { tracing::error!(\"unparseable output: {llm_output:?}\"); return Err(e.into()); }\n};","handlingStrategy":"try-catch","validationCode":"fn has_json_shape(s: &str) -> bool { let t = s.trim(); t.starts_with('{') || t.starts_with('[') || t.contains(\"```\") }","typeGuard":null,"tryCatchPattern":"match jsonish::from_str(&t, out) {\n    Ok(v) => v,\n    Err(e) if e.to_string() == \"Failed to parse JSON\" => {\n        tracing::warn!(\"no JSON in output: {out:.200}\");\n        retry_with_format_instruction()\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Require JSON-only output in the prompt","Check the response contains braces before parsing","Keep a retry path with the format error fed back to the model"],"tags":["json","parsing","llm-output"],"backgroundTag":"json-parse-error","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"}