mermaid-js/mermaid · error · Error

Packet block ${start} - ${end ?? start} is not contiguous. I

Error message

Packet block ${start} - ${end ?? start} is not contiguous. It should start from ${lastBit + 1}.

What it means

Thrown by the packet populate loop when a block's start does not equal lastBit+1, i.e. the block leaves a gap or overlaps the previous block. Packet layouts must be contiguous: each block must begin exactly where the previous one ended. The error message reports the expected starting bit so the author can fix the offset.

Source

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

import { PacketDB } from './db.js';
import type { PacketBlock, PacketWord } from './types.js';

const maxPacketSize = 10_000;

const populate = (ast: Packet, db: PacketDB) => {
  populateCommonDb(ast, db);
  let lastBit = -1;
  let word: PacketWord = [];
  let row = 1;
  const { bitsPerRow } = db.getConfig();

  for (let { start, end, bits, label } of ast.blocks) {
    if (start !== undefined && end !== undefined && end < start) {
      throw new Error(`Packet block ${start} - ${end} is invalid. End must be greater than start.`);
    }
    start ??= lastBit + 1;
    if (start !== lastBit + 1) {
      throw new Error(
        `Packet block ${start} - ${end ?? start} is not contiguous. It should start from ${
          lastBit + 1
        }.`
      );
    }
    if (bits === 0) {
      throw new Error(`Packet block ${start} is invalid. Cannot have a zero bit field.`);
    }
    end ??= start + (bits ?? 1) - 1;
    bits ??= end - start + 1;
    lastBit = end;
    log.debug(`Packet block ${start} - ${lastBit} with label ${label}`);

    while (word.length <= bitsPerRow + 1 && db.getPacket().length < maxPacketSize) {
      const [block, nextBlock] = getNextFittingBlock({ start, end, bits, label }, row, bitsPerRow);
      word.push(block);
      if (block.end + 1 === row * bitsPerRow) {
        db.pushWord(word);

View on GitHub (pinned to d93e9c88c0)

Solutions

  1. Make each block start exactly at the previous block's end+1; the error message tells you the expected value.
  2. Omit start on non-first blocks to let mermaid auto-continue from lastBit+1.
  3. For intentional gaps, insert an unnamed block covering the reserved bits.
  4. Lay out fields sequentially from bit 0 without skipping.

Example fix

// before — gap between blocks
packet-beta
  0-7: Field A
  16-23: Field B   // gap at 8-15

// after — contiguous, or omit start
packet-beta
  0-7: Field A
  8-15: Reserved
  16-23: Field B
Defensive patterns

Strategy: validation

Validate before calling

// Validate packet contiguity before render.
function validateContiguity(blocks: {start?:number;end?:number;bits?:number}[]): string[] {
  const errors: string[] = [];
  let lastBit = -1;
  for (const b of blocks) {
    const start = b.start ?? lastBit + 1;
    if (start !== lastBit + 1) {
      errors.push(`Block starting at ${start} is not contiguous (expected ${lastBit + 1})`);
    }
    const end = b.end ?? start + (b.bits ?? 1) - 1;
    lastBit = end;
  }
  return errors;
}

Try / catch

try {
  await mermaid.render('g', diagramText);
} catch (e) {
  if (e instanceof Error && /is not contiguous/.test(e.message)) {
    showUserError('Packet blocks must be contiguous with no gaps or overlaps. The error message names the expected start bit.');
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Declaring a block with start greater than lastBit+1 (a gap); declaring start less than lastBit+1 (an overlap); providing only start on a non-first block where it doesn't continue from the previous end.

Common situations: Hand-authoring a packet field layout and losing count of bit positions; leaving intentional gaps (unsupported — use reserved/empty blocks instead); renumbering fields without updating subsequent starts.

Related errors


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