Stirling-Tools/Stirling-PDF · error · Error

Invalid scale ratio: ${ratio}

Error message

Invalid scale ratio: ${ratio}

What it means

Thrown by calculateScaleFactor when the passed ratio fails Number.isFinite(ratio) || ratio <= 0. ratio is multiplied against a unit factor to produce a scale, so NaN, Infinity, or non-positive values are rejected as mathematically invalid (they would yield a nonsensical measurement scale).

Source

Thrown at frontend/editor/src/core/utils/measurementUtils.ts:46

function normalizeUnit(unit: string): string {
  return unit.toLowerCase().trim();
}

function isMeasurementUnit(unit: string): unit is MeasurementUnit {
  return Object.hasOwn(POINT_TO_UNIT, unit);
}

export function getUnitFactor(unit: string): number | undefined {
  const normalized = normalizeUnit(unit);
  if (!isMeasurementUnit(normalized)) {
    return undefined;
  }
  return POINT_TO_UNIT[normalized];
}

export function calculateScaleFactor(ratio: number, unit: string): number {
  if (!Number.isFinite(ratio) || ratio <= 0) {
    throw new Error(`Invalid scale ratio: ${ratio}`);
  }

  const normalized = normalizeUnit(unit);
  if (!isMeasurementUnit(normalized)) {
    throw new Error(`Unsupported unit: ${unit}`);
  }

  return POINT_TO_UNIT[normalized] * ratio;
}

export function generateScaleLabel(ratio: number | null, unit: string): string {
  if (ratio === null || ratio === undefined) {
    return unit;
  }
  const display = Number.isInteger(ratio)
    ? ratio.toString()
    : ratio.toFixed(2).replace(/\.?0+$/, "");
  return `1:${display} (${unit})`;

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Validate and coerce the ratio before calling: ensure it is a finite number > 0.
  2. If the ratio originates from user input, parse with parsePresetRatio and reject null before calling calculateScaleFactor.
  3. Guard calibration handlers against coincident points (distance === 0) and prompt the user to drag further.
  4. Default to a sane ratio (e.g. 1) with a warning instead of forwarding an invalid value.

Example fix

// before
const factor = calculateScaleFactor(ratio, unit);

// after
if (!Number.isFinite(ratio) || ratio <= 0) {
  throw new Error(`Cannot calibrate: scale ratio is ${ratio}. Pick two distinct points.`);
}
const factor = calculateScaleFactor(ratio, unit);
Defensive patterns

Strategy: validation

Validate before calling

function assertValidRatio(ratio: number): void {
  if (!Number.isFinite(ratio) || ratio <= 0) {
    throw new Error(`Cannot use scale ratio ${ratio}: must be a positive finite number.`);
  }
}

assertValidRatio(ratio);
const factor = calculateScaleFactor(ratio, unit);

Type guard

const isValidRatio = (ratio: unknown): ratio is number =>
  typeof ratio === "number" && Number.isFinite(ratio) && ratio > 0;

Prevention

When it happens

Trigger: Calling calculateScaleFactor(NaN, 'cm'); passing a ratio parsed from a malformed preset string (e.g. '1:abc'); dividing by zero upstream and forwarding the result; a measurement tool emitting 0 or negative from a degenerate two-click calibration.

Common situations: Two calibration clicks on the exact same point (distance 0); user typing non-numeric text into a ratio field; float underflow producing 0 from extremely close points.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/003081773fb3d185. Report an issue: GitHub.