mermaid-js/mermaid · error · Error

start should have been set during first phase

Error message

start should have been set during first phase

What it means

Thrown by getNextFittingBlock when block.start is undefined. The populate loop's first phase is supposed to assign start (either from the AST or defaulted to lastBit+1) before ever calling getNextFittingBlock, so an undefined start here means an internal invariant was violated. It is not reachable through valid user input — the contiguity and end<start guards run first.

Source

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

        word = [];
        row++;
      }
      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,

View on GitHub (pinned to d93e9c88c0)

Solutions

  1. Report upstream as a mermaid bug with the reproducing packet-beta input and version.
  2. Upgrade to the latest mermaid release.
  3. If calling getNextFittingBlock directly in a fork, ensure start and end are always set on the block before invocation.
  4. Audit the destructure rebinding at the loop tail to confirm nextBlock always carries start.
Defensive patterns

Strategy: type-guard

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: An internal bug where the block object passed into getNextFittingBlock lost its start field; programmatic construction of a PacketBlock with start omitted and fed directly to the layout; a regression in the populate loop's variable rebinding (the ({ start, end, bits, label } = nextBlock) destructure).

Common situations: Appears only after internal mermaid changes or custom forks; not triggerable from packet-beta text syntax in released versions.

Related errors


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