jackwener/OpenCLI · error · ArgumentError

${label} must be a ${positive ? 'positive ' : ''}finite numb

Error message

${label} must be a ${positive ? 'positive ' : ''}finite number

What it means

normalizeNumber() validates that a caller-supplied value converts to a finite JavaScript number before it is used in GeoGebra commands. It throws ArgumentError whenever the raw value is null/empty without a defaultValue, or Number(value) yields NaN/Infinity, or the `positive` flag is set and the value is <= 0. The label parameter names the offending field so callers can tell which argument failed.

Source

Thrown at clis/geogebra/utils.js:45

  if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(normalized)) {
    throw new ArgumentError(`${label} must be an ASCII GeoGebra label like A, B1, or poly_1`);
  }
  return normalized;
}

export function normalizeLabelList(value, label, min, max = Infinity) {
  const parts = String(value ?? '').split(',').map(s => s.trim()).filter(Boolean);
  if (parts.length < min || parts.length > max) {
    throw new ArgumentError(`${label} must contain ${min === max ? min : `${min}-${max}`} comma-separated labels`);
  }
  return parts.map((part, idx) => normalizeLabel(part, `${label}[${idx + 1}]`));
}

export function normalizeNumber(value, label, { defaultValue, positive = false } = {}) {
  const raw = value == null || value === '' ? defaultValue : value;
  const number = Number(raw);
  if (!Number.isFinite(number) || (positive && number <= 0)) {
    throw new ArgumentError(`${label} must be a ${positive ? 'positive ' : ''}finite number`);
  }
  return number;
}

export function normalizeCoords(value) {
  const parts = String(value ?? '').split(',').map(s => s.trim());
  if (parts.length !== 2) {
    throw new ArgumentError('coords must be in "x,y" format (e.g. "1,2")');
  }
  return parts.map((part, idx) => normalizeNumber(part, idx === 0 ? 'x' : 'y'));
}

export function requireGgbSuccess(result, message) {
  if (!isPlainObject(result)) {
    throw new CommandExecutionError(`${message}: malformed GeoGebra result`);
  }
  if (!result.ok) {
    throw new CommandExecutionError(result.error || message);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Print/inspect the value passed for the labeled field and ensure it is a plain finite number (e.g. Number.isFinite(Number(value))).
  2. Supply a defaultValue option for optional parameters so empty input does not throw.
  3. If the field must be positive, pass a value > 0 (e.g. clamp with Math.max(0.1, value)).
  4. Fix the source of the bad input: correct the CLI flag, env var, or config entry that feeds this argument.

Example fix

// before
normalizeNumber(opts.timeout, 'timeoutMs', { positive: true })
// after
const timeoutMs = normalizeNumber(opts.timeout ?? 5000, 'timeoutMs', { defaultValue: 5000, positive: true });
Defensive patterns

Strategy: validation

Validate before calling

function isValidNumber(v) { return v !== '' && v != null && Number.isFinite(Number(v)); }
if (!isValidNumber(size)) throw new Error('size must be a finite number');

Type guard

const isFiniteNumber = (v) => typeof v === 'number' && Number.isFinite(v);

Try / catch

try { const n = normalizeNumber(input, 'size', { positive: true }); } catch (e) { if (e instanceof ArgumentError) { console.error(`Bad input for ${e.message}`); } else throw e; }

Prevention

When it happens

Trigger: Passing a non-numeric string (e.g. 'abc'), null/undefined with no defaultValue, an empty string, Infinity, or a zero/negative value while positive=true (e.g. normalizeNumber('0', 'size', { positive: true })). All callers (size, normalizeCoords, normalizedMinCount, normalizedTimeoutMs) route through this check.

Common situations: CLI flags typed incorrectly (missing digits, commas as decimal separators under some locales), config files with blank fields, script variables that are undefined due to a typo, or passing a numeric string like '1e999' which parses to Infinity.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/6069abaa0575f94d. Report an issue: GitHub.