mermaid-js/mermaid · error · Error

end should have been set during first phase

Error message

end should have been set during first phase

What it means

Thrown by getNextFittingBlock when block.end is undefined. Symmetric to the start check: the populate loop's first phase must compute end (from explicit end or start+bits-1) before layout, so an undefined end here is an internal invariant violation, not a user-facing validation.

Source

Thrown at packages/mermaid/src/diagrams/packet/parser.ts:64

      if (!nextBlock) {
        break;
      }
      ({ start, end, bits, label } = nextBlock);
    }
  }
  db.pushWord(word);
};

const getNextFittingBlock = (
  block: PacketBlock,
  row: number,
  bitsPerRow: number
): [Required<PacketBlock>, PacketBlock | undefined] => {
  if (block.start === undefined) {
    throw new Error('start should have been set during first phase');
  }
  if (block.end === undefined) {
    throw new Error('end should have been set during first phase');
  }

  if (block.start > block.end) {
    throw new Error(`Block start ${block.start} is greater than block end ${block.end}.`);
  }

  if (block.end + 1 <= row * bitsPerRow) {
    return [block as Required<PacketBlock>, undefined];
  }

  const rowEnd = row * bitsPerRow - 1;
  const rowStart = row * bitsPerRow;
  return [
    {
      start: block.start,
      end: rowEnd,
      label: block.label,
      bits: rowEnd - block.start,

View on GitHub (pinned to d93e9c88c0)

Solutions

  1. Report upstream with the packet-beta input and mermaid version.
  2. Upgrade mermaid.
  3. In a fork, guarantee end is set on every block before calling getNextFittingBlock.
  4. Verify the nextBlock returned by getNextFittingBlock always has end populated for multi-row splits.
Defensive patterns

Strategy: type-guard

Type guard

function blockHasEnd(block: {end?:number}): block is {end:number} {
  return block.end !== undefined;
}

Try / catch

try {
  await mermaid.parse(text);
} catch (e) {
  if (e instanceof Error && /end should have been set during first phase/.test(e.message)) {
    reportBug(e, text);
  } else throw e;
}

Prevention

When it happens

Trigger: Internal bug where end was not assigned before getNextFittingBlock; a PacketBlock constructed programmatically with end omitted; regression in the populate loop destructure that drops end.

Common situations: Not reachable via normal packet-beta text; only with custom integrations, forks, or mermaid internal regressions.

Related errors


AI-assisted analysis of mermaid-js/mermaid@d93e9c88c0 (2026-08-12). Data as JSON: /api/errors/455f837b92980864. Report an issue: GitHub.