{"record":{"id":"d177151b4ac7ac5e","repo":"mermaid-js/mermaid","slug":"parsing-failed-lexererrors-parsererrors-d17715","errorCode":null,"errorMessage":"Parsing failed: ${lexerErrors} ${parserErrors}","messagePattern":"Parsing failed: (.+?) (.+?)","errorType":"validation","errorClass":"MermaidParseError","httpStatus":null,"severity":"error","filePath":"packages/mermaid/src/diagrams/railroad/parser/railroadParser.ts","lineNumber":99,"sourceCode":"\nconst populateDb = (ast: Railroad): void => {\n  populateCommonDb(ast, db);\n\n  if (ast.title) {\n    db.setTitle(ast.title);\n  }\n\n  ast.rules.map((rule) => db.addRule(transformRule(rule)));\n};\n\nexport const parser: ParserDefinition = {\n  parse: (input: string): void => {\n    db.clear();\n    log.debug('[Railroad Parser] Starting Langium parse');\n\n    const result = langiumParser.parse<Railroad>(input);\n    if (result.lexerErrors.length > 0 || result.parserErrors.length > 0) {\n      throw new MermaidParseError(result);\n    }\n\n    const ast = result.value;\n    log.debug('[Railroad Parser] Parsed rules:', ast.rules.length);\n\n    populateDb(ast);\n    log.debug('[Railroad Parser] Parse complete');\n  },\n  parser: {\n    yy: db,\n  },\n};\n\nexport default parser;\n","sourceCodeStart":81,"sourceCodeEnd":114,"githubUrl":"https://github.com/mermaid-js/mermaid/blob/d93e9c88c01a599c062ee6a3f1462e3558ac6b90/packages/mermaid/src/diagrams/railroad/parser/railroadParser.ts#L81-L114","documentation":"Generic railroad grammar parse guard (the default `railroad` flavor). Runs Langium, and if lexerErrors or parserErrors are present, throws a MermaidParseError bundling the full ParseResult so the caller can read token-level diagnostics. Aborts before any rule is added to the db.","triggerScenarios":"parser.parse(input) on the generic railroad ParserDefinition with input violating the default railroad grammar — undeclared rule reference, unbalanced grouping, invalid operator, stray character.","commonSituations":"Default railroad syntax mixed with one of the dialect-specific flavors; copy-paste from a source that uses different operators; truncation; invisible/non-ASCII characters from rich text paste.","solutions":["Address the first reported lexer/parser error using its line/column.","If the input is ABNF/EBNF/PEG, switch to the matching dialect diagram.","Strip non-ASCII and normalise quotes before parsing.","Catch MermaidParseError and surface e.result.lexerErrors/parserErrors."],"exampleFix":"// before — unbalanced grouping\nrule ::= 'a' ( 'b' | 'c'\n\n// after\nrule ::= 'a' ( 'b' | 'c' )","handlingStrategy":"try-catch","validationCode":"// Strip non-ASCII and balance-check parentheses as a cheap pre-check\nconst cleaned = input.replace(/[^\\x00-\\x7F]/g, '');\nconst open = (cleaned.match(/\\(/g) || []).length;\nconst close = (cleaned.match(/\\)/g) || []).length;\nif (open !== close) throw new Error('Unbalanced parentheses');","typeGuard":"import { MermaidParseError } from '@mermaid-js/parser';\nconst isMermaidParseError = (e): e is MermaidParseError => e instanceof MermaidParseError;","tryCatchPattern":"try {\n  parser.parse(input);\n} catch (e) {\n  if (e instanceof MermaidParseError) {\n    reportErrors([...e.result.lexerErrors, ...e.result.parserErrors]);\n  } else { throw e; }\n}","preventionTips":["Normalise quotes and strip stray unicode before parsing.","Match the diagram flavor to your grammar.","Use e.result for precise diagnostics."],"tags":["railroad","parser","syntax-error","langium"],"backgroundTag":null,"analyzedSha":"d93e9c88c01a599c062ee6a3f1462e3558ac6b90","analyzedAt":"2026-08-12T06:23:11.304Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}