{"record":{"id":"efd86fb790afc6e5","repo":"BoundaryML/baml","slug":"encountered-impossible-raw-string-during-parsing","errorCode":null,"errorMessage":"Encountered impossible raw string during parsing","messagePattern":"Encountered impossible raw string during parsing","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-lib/ast/src/parser/parse_expression.rs","lineNumber":558,"sourceCode":"\n    for current in token.into_inner() {\n        match current.as_rule() {\n            Rule::raw_string_literal_content_1\n            | Rule::raw_string_literal_content_2\n            | Rule::raw_string_literal_content_3\n            | Rule::raw_string_literal_content_4\n            | Rule::raw_string_literal_content_5 => {\n                content = Some((\n                    current.as_str().to_string(),\n                    diagnostics.span(current.as_span()),\n                ));\n            }\n            _ => unreachable_rule(&current, \"raw_string_literal\", diagnostics),\n        };\n    }\n    match content {\n        Some((content, span)) => RawString::new(content, span),\n        _ => unreachable!(\"Encountered impossible raw string during parsing\"),\n    }\n}\n\n// NOTE(sam): this doesn't handle unicode escape sequences e.g. \\u1234\n// also this has panicks in it (see the hex logic)\nfn unescape_string(val: &str) -> String {\n    let mut result = String::with_capacity(val.len());\n    let mut chars = val.chars().peekable();\n\n    while let Some(c) = chars.next() {\n        if c == '\\\\' {\n            match chars.next() {\n                Some('n') => result.push('\\n'),\n                Some('r') => result.push('\\r'),\n                Some('t') => result.push('\\t'),\n                Some('0') => result.push('\\0'),\n                Some('\\'') => result.push('\\''),\n                Some('\\\"') => result.push('\\\"'),","sourceCodeStart":540,"sourceCodeEnd":576,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-lib/ast/src/parser/parse_expression.rs#L540-L576","documentation":"This is a `unreachable!()` panic in `parse_raw_string` in the BAML AST parser. After looping over the children of a `raw_string_literal` pair, the function asserts it captured a `(content, span)` tuple; reaching the fallback means no child assigned content — the raw-string grammar produced a node with no recognized content token, breaking the grammar/parser contract. It indicates the raw string literal parsed to an empty/unrecognized shape.","triggerScenarios":"Parsing a raw string literal (e.g. `#\"...\"#`) whose `raw_string_literal` pair contains only rules not matched inside the loop — possible after a grammar change to the raw-string rules without updating `parse_raw_string`, or a zero-child raw_string_literal pair.","commonSituations":"Using raw string syntax with unusual hash counts or delimiters in a BAML version where raw-string lexing changed; contributors editing baml.pest raw_string_literal rules without updating the parser; corrupted/empty string token reaching the parser.","solutions":["Rewrite the raw string using standard BAML raw-string syntax (`#\"text\"#`) with balanced delimiters","Replace the raw string with a regular quoted string or template string if the escaping allows it","Check the BAML source at the panic span for a truncated or malformed raw string and fix the delimiters","If you are a contributor: extend `parse_raw_string`'s loop to handle all child rules of `raw_string_literal` in baml.pest"],"exampleFix":"// before (malformed raw string)\nlet s #\"unterminated\n// after\nlet s #\"terminated\"#","handlingStrategy":"validation","validationCode":"// Validate raw string delimiters are balanced before parsing:\nfunction assertBalancedRawString(src) {\n  const opens = (src.match(/#\"/g) || []).length;\n  const closes = (src.match(/\"#/g) || []).length;\n  if (opens !== closes) {\n    throw new Error(`Unbalanced raw string delimiters will crash the BAML parser: ${src}`);\n  }\n}","typeGuard":"const isWellFormedRawString = (s) => /^#\"[\\s\\S]*\"#$/.test(s.trim());","tryCatchPattern":"catch (panicOutput) {\n  if (String(panicOutput).includes('Encountered impossible raw string')) {\n    logParserBug('raw_string_literal yielded no content', panicOutput);\n    return null;\n  }\n  throw panicOutput;\n}","preventionTips":["Always close raw strings with the matching `\"#` delimiter","Prefer plain quoted strings when escaping is trivial","Update parse_raw_string whenever raw_string_literal rules change in baml.pest","Add parser tests for empty and multi-hash raw strings"],"tags":["parser","panic","raw-string","rust"],"backgroundTag":"internal-invariant-violation","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"}