actualbudget/actual · error

Invalid ${flagName}: "${value}". Expected a non-negative int

Error message

Invalid ${flagName}: "${value}". Expected a non-negative integer.

What it means

parseNonNegativeIntFlag wraps parseIntFlag and additionally rejects negative integers. It throws when the parsed value is less than 0.

Source

Thrown at packages/cli/src/utils.ts:28

  }
  return value === 'true';
}

export function parseIntFlag(value: string, flagName: string): number {
  const parsed = value.trim() === '' ? NaN : Number(value);
  if (!Number.isInteger(parsed)) {
    throw new Error(`Invalid ${flagName}: "${value}". Expected an integer.`);
  }
  return parsed;
}

export function parseNonNegativeIntFlag(
  value: string,
  flagName: string,
): number {
  const parsed = parseIntFlag(value, flagName);
  if (parsed < 0) {
    throw new Error(
      `Invalid ${flagName}: "${value}". Expected a non-negative integer.`,
    );
  }
  return parsed;
}

export function parseBoolEnv(
  raw: string | undefined,
  source: string,
): boolean | undefined {
  if (raw === undefined) return undefined;
  const lower = raw.toLowerCase();
  if (raw === '1' || lower === 'true') return true;
  if (raw === '0' || lower === 'false') return false;
  throw new Error(
    `Invalid ${source}: "${raw}". Expected "true", "false", "1", or "0".`,
  );
}

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Provide a zero or positive integer value.
  2. Use the documented way to express "no limit" (omit the flag) instead of a negative sentinel.
  3. Clamp computed values with Math.max(0, value) before passing.

Example fix

// before
const limit = parseNonNegativeIntFlag('-1', '--limit');
// after
const limit = parseNonNegativeIntFlag(String(Math.max(0, n)), '--limit');
Defensive patterns

Strategy: validation

Validate before calling

function isValidNonNegativeInt(value: string): boolean {
  const n = Number(value);
  return Number.isInteger(n) && n >= 0;
}

Try / catch

let limit: number;
try {
  limit = parseNonNegativeIntFlag(value, '--limit');
} catch (err) {
  console.error((err as Error).message);
  process.exit(1);
}

Prevention

When it happens

Trigger: Calling parseNonNegativeIntFlag with a negative value such as "-1" or "-5"; it is invoked by parseNonNegativeIntEnv for environment-sourced values.

Common situations: Setting an env var like ACTUAL_LIMIT=-1 intending "unlimited"; offset/limit flags computed from arithmetic that went negative.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/7ceb8d3d33fffbce. Report an issue: GitHub.