mermaid-js/mermaid · error · Error

Packet block ${start} is invalid. Cannot have a zero bit fie

Error message

Packet block ${start} is invalid. Cannot have a zero bit field.

What it means

Thrown by the packet populate loop when a block's bits field is exactly 0. A zero-width field has no bits to render and is invalid; the check runs after start/end contiguity is verified, so it specifically catches an explicit bits: 0 (or a computed zero via end-start+1 when end<start after the earlier guard, though that path is already rejected).

Source

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

  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);
        word = [];
        row++;
      }
      if (!nextBlock) {
        break;
      }
      ({ start, end, bits, label } = nextBlock);

View on GitHub (pinned to d93e9c88c0)

Solutions

  1. Set bits to at least 1, or remove the block entirely if it represents nothing.
  2. If you need a visual spacer, use a small non-zero reserved block instead.
  3. Check any code generator that emits packet syntax and ensure it never produces bits: 0.

Example fix

// before
packet-beta
  0-7: Field A
  8-7: Zero width   // bits computes to 0

// after
packet-beta
  0-7: Field A
  8: Single bit field
Defensive patterns

Strategy: validation

Validate before calling

function validateNoZeroBits(blocks: {start?:number;end?:number;bits?:number}[]): string[] {
  const errors: string[] = [];
  for (const b of blocks) {
    if (b.bits === 0) errors.push(`Block at ${b.start ?? '?'} has zero bits`);
  }
  return errors;
}

Type guard

function hasPositiveBits(bits: number | undefined): boolean {
  return bits === undefined || bits > 0;
}

Try / catch

try {
  await mermaid.render('g', diagramText);
} catch (e) {
  if (e instanceof Error && /Cannot have a zero bit field/.test(e.message)) {
    showUserError('A packet block declares zero bits. Set bits >= 1 or remove the block.');
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Declaring a packet block with bits: 0; writing a range where the computed width collapses to zero.

Common situations: Placeholder/reserved field left as zero by mistake; templating system emitting bits:0 for optional fields; misunderstanding that every block must consume at least one bit.

Related errors


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