{"record":{"id":"d0e445d7cde469b8","repo":"mermaid-js/mermaid","slug":"block-start-block-start-is-greater-than-block-e","errorCode":null,"errorMessage":"Block start ${block.start} is greater than block end ${block.end}.","messagePattern":"Block start (.+?) is greater than block end (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mermaid/src/diagrams/packet/parser.ts","lineNumber":68,"sourceCode":"    }\n  }\n  db.pushWord(word);\n};\n\nconst getNextFittingBlock = (\n  block: PacketBlock,\n  row: number,\n  bitsPerRow: number\n): [Required<PacketBlock>, PacketBlock | undefined] => {\n  if (block.start === undefined) {\n    throw new Error('start should have been set during first phase');\n  }\n  if (block.end === undefined) {\n    throw new Error('end should have been set during first phase');\n  }\n\n  if (block.start > block.end) {\n    throw new Error(`Block start ${block.start} is greater than block end ${block.end}.`);\n  }\n\n  if (block.end + 1 <= row * bitsPerRow) {\n    return [block as Required<PacketBlock>, undefined];\n  }\n\n  const rowEnd = row * bitsPerRow - 1;\n  const rowStart = row * bitsPerRow;\n  return [\n    {\n      start: block.start,\n      end: rowEnd,\n      label: block.label,\n      bits: rowEnd - block.start,\n    },\n    {\n      start: rowStart,\n      end: block.end,","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/mermaid-js/mermaid/blob/d93e9c88c01a599c062ee6a3f1462e3558ac6b90/packages/mermaid/src/diagrams/packet/parser.ts#L50-L86","documentation":"Thrown by getNextFittingBlock after the undefined checks pass but block.start is greater than block.end. Since the populate loop already rejects user-supplied start>end and auto-computes end = start+bits-1 (which is >= start for bits>=1), reaching this guard means an internal logic error produced an inverted range — most likely from the multi-row split arithmetic in getNextFittingBlock itself.","triggerScenarios":"A block spanning multiple rows where the split computation yields start>end; an internal regression in the rowEnd/rowStart math; programmatic block construction with start>end that bypassed the populate guards.","commonSituations":"Not triggerable from valid packet-beta text in stable releases; appears with edge-case block sizes near row boundaries or after internal refactors.","solutions":["Report upstream with the exact packet-beta input that reproduces and the mermaid version.","Upgrade mermaid.","If reproducing in a fork, log block.start/block.end at the split boundary to find the arithmetic error.","Simplify the packet layout to single-row blocks as a workaround while the bug is fixed."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function blockStartLeEnd(block: {start:number;end:number}): boolean {\n  return block.start <= block.end;\n}","tryCatchPattern":"try {\n  await mermaid.parse(text);\n} catch (e) {\n  if (e instanceof Error && /Block start .* is greater than block end/.test(e.message)) {\n    reportBug(e, text);\n  } else throw e;\n}","preventionTips":["Report upstream with the reproducing packet-beta input.","Simplify multi-row blocks as a workaround.","Keep mermaid updated."],"tags":["mermaid","packet","parsing","internal-invariant"],"backgroundTag":null,"analyzedSha":"d93e9c88c01a599c062ee6a3f1462e3558ac6b90","analyzedAt":"2026-08-12T06:23:11.304Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}