mermaid-js/mermaid · error

Position must be a non-negative integer.${position}

Error message

Position must be a non-negative integer.${position}

What it means

Thrown by calculateBlockPosition when `position` is negative or not an integer. Position is the zero-based index of a block within its parent's grid; negative indices and fractional positions have no meaning in the grid math. Note the message concatenates the raw position value onto the string with no separator, so the number appears directly appended.

Source

Thrown at packages/mermaid/src/diagrams/block/layout.ts:20

import type { Block } from './blockTypes.js';
import { log } from '../../logger.js';
import { getConfig } from '../../diagram-api/diagramAPI.js';

interface BlockPosition {
  px: number;
  py: number;
}

export function calculateBlockPosition(columns: number, position: number): BlockPosition {
  // log.debug('calculateBlockPosition abc89', columns, position);
  // Ensure that columns is a positive integer
  if (columns === 0 || !Number.isInteger(columns)) {
    throw new Error('Columns must be an integer !== 0.');
  }

  // Ensure that position is a non-negative integer
  if (position < 0 || !Number.isInteger(position)) {
    throw new Error('Position must be a non-negative integer.' + position);
  }

  if (columns < 0) {
    // Auto columns is set
    return { px: position, py: 0 };
  }
  if (columns === 1) {
    // Auto columns is set
    return { px: 0, py: position };
  }
  // Calculate posX and posY
  const px = position % columns;
  const py = Math.floor(position / columns);
  // log.debug('calculateBlockPosition abc89', columns, position, '=> (', px, py, ')');
  return { px, py };
}

const getMaxChildSize = (block: Block) => {

View on GitHub (pinned to d93e9c88c0)

Solutions

  1. Ensure position is >= 0 and an integer before calling.
  2. Clamp computed positions to 0 and floor/round any fractional result.

Example fix

// before
calculateBlockPosition(3, -1);
calculateBlockPosition(3, 1.5);
// after
calculateBlockPosition(3, Math.max(0, Math.floor(rawIndex)));
Defensive patterns

Strategy: validation

Validate before calling

function calculateBlockPositionSafe(columns, position) {
  if (position < 0 || !Number.isInteger(position)) {
    throw new Error(`position must be a non-negative integer; got ${position}`);
  }
  return calculateBlockPosition(columns, position);
}

Type guard

const isValidPosition = (p) => Number.isInteger(p) && p >= 0;

Prevention

When it happens

Trigger: Calling calculateBlockPosition(cols, -1) or calculateBlockPosition(cols, 1.5). Internally position is derived from iteration order and widthInColumns accounting, so a negative value usually signals an underflow in that accounting.

Common situations: Off-by-one errors in computed positions; integer underflow when subtracting widthInColumns; floating-point positions from division that should have been floored.

Related errors


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