mermaid-js/mermaid · error

${context} must be between 0-1 (decimal) or 0-100 (percentag

Error message

${context} must be between 0-1 (decimal) or 0-100 (percentage). Received: ${value}

What it means

toPercent() normalises wardley coordinate values: a value <= 1 is treated as a decimal and multiplied by 100; anything else is treated as a percentage and used as-is. If the resulting number falls outside [0,100], it throws naming the context (e.g. component/visibility/evolution) and the offending raw value. Both visibility and evolution pass through it.

Source

Thrown at packages/mermaid/src/diagrams/wardley/wardleyParser.ts:12

import type { Wardley } from '@mermaid-js/parser';
import { parse } from '@mermaid-js/parser';
import type { ParserDefinition } from '../../diagram-api/types.js';
import { log } from '../../logger.js';
import { populateCommonDb } from '../common/populateCommonDb.js';
import type { WardleyDB } from './wardleyTypes.js';

const toPercent = (value: number, context: string): number => {
  // Accept values in 0-1 range (converted to percentage) or 0-100 range (used as-is)
  const normalized = value <= 1 ? value * 100 : value;
  if (normalized < 0 || normalized > 100) {
    throw new Error(
      `${context} must be between 0-1 (decimal) or 0-100 (percentage). Received: ${value}`
    );
  }
  return normalized;
};

const toCoordinates = (
  visibility: number,
  evolution: number,
  context: string
): { x: number; y: number } => {
  return {
    x: toPercent(evolution, `${context} evolution`),
    y: toPercent(visibility, `${context} visibility`),
  };
};

const getFlowFromPort = (port?: string): 'forward' | 'backward' | 'bidirectional' | undefined => {

View on GitHub (pinned to d93e9c88c0)

Solutions

  1. Pick one unit per diagram and stick to it: either all decimals 0..1 or all percentages 0..100.
  2. Clamp the offending value into [0,1] or [0,100] according to your chosen unit.
  3. Avoid values in (1, 100] if you intended decimals — they are read as percentages.
  4. Validate coordinates upstream against the same rule before rendering.

Example fix

// before
component Foo [150, 0.8]  // 150% -> throws

// after (percentage unit)
component Foo [80, 50]
// or (decimal unit)
component Foo [0.8, 0.5]
Defensive patterns

Strategy: validation

Validate before calling

// Validate wardley coordinates with the same rule the parser uses
function toPercent(value, context) {
  const normalized = value <= 1 ? value * 100 : value;
  if (normalized < 0 || normalized > 100) {
    throw new Error(`${context} out of range: ${value}`);
  }
  return normalized;
}
// pick one unit and validate all coordinates before rendering

Type guard

const isValidCoordinate = (v: number): boolean => {
  const n = v <= 1 ? v * 100 : v;
  return Number.isFinite(v) && n >= 0 && n <= 100;
};

Try / catch

try {
  await mermaid.run({ nodes: [el] });
} catch (e) {
  if (e instanceof Error && /must be between 0-1/.test(e.message)) {
    // read the bad value from the message and clamp/convert it
  } else { throw e; }
}

Prevention

When it happens

Trigger: Supplying visibility or evolution values that are negative, greater than 100, or in an ambiguous range; e.g. `[-5, 0.5]`, `[0.5, 150]`, or `[2, 0.8]` (2 is >1 so treated as 2%, valid, but surprises users who meant 0..1). Note values like 1.5 are treated as percentages (1.5%) because only <=1 scales.

Common situations: Unit confusion — mixing decimal (0..1) and percentage (0..100) in one diagram; off-by-100 typos; copying coordinates from a tool that uses a 0..255 or 0..1 scale differently; negative margins.

Related errors


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