affaan-m/ECC · warning

${flagName} must be a positive number

Error message

${flagName} must be a positive number

What it means

readPositiveNumber parses a numeric flag value and requires Number(value) to be finite and strictly greater than zero; anything else throws. It deliberately accepts non-integers (e.g. 1.5), so it is used for flags that legitimately allow fractions. Affects --bash-timeout-seconds, --wake-grace-multiplier, --watch-interval-seconds.

Source

Thrown at scripts/loop-status.js:51

    '',
    'Examples:',
    '  node scripts/loop-status.js --json',
    '  node scripts/loop-status.js --transcript ~/.claude/projects/-repo/session.jsonl'
  ].join('\n'));
}

function readValue(args, index, flagName) {
  const value = args[index + 1];
  if (!value || value.startsWith('--')) {
    throw new Error(`${flagName} requires a value`);
  }
  return value;
}

function readPositiveNumber(value, flagName) {
  const number = Number(value);
  if (!Number.isFinite(number) || number <= 0) {
    throw new Error(`${flagName} must be a positive number`);
  }
  return number;
}

function readPositiveInteger(value, flagName) {
  const number = readPositiveNumber(value, flagName);
  if (!Number.isInteger(number)) {
    throw new Error(`${flagName} must be a positive integer`);
  }
  return number;
}

function parseArgs(argv) {
  const args = argv.slice(2);
  const options = {
    bashTimeoutSeconds: DEFAULT_BASH_TIMEOUT_SECONDS,
    exitCode: false,
    home: null,

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Pass a positive number, e.g. `--watch-interval-seconds 2.5`.
  2. If you need an integer-only flag, use --limit or --watch-count instead (those use readPositiveInteger).
  3. Guard shell variables: `--watch-interval-seconds "${INTERVAL:-5}"`.
  4. Remove the flag to accept the documented default instead of forcing 0.

Example fix

# before
node scripts/loop-status.js --watch --watch-interval-seconds 0

# after
node scripts/loop-status.js --watch --watch-interval-seconds 2
Defensive patterns

Strategy: validation

Validate before calling

// Validate that numeric flags are finite and > 0 before invoking.
function isPositiveNumber(v) { const n = Number(v); return Number.isFinite(n) && n > 0; }
function validatePositiveNumbers(flagMap) {
  for (const [flag, raw] of Object.entries(flagMap)) {
    if (raw !== undefined && !isPositiveNumber(raw)) {
      throw new Error(`${flag} must be a positive number`);
    }
  }
}

Type guard

/** @returns {n is number} */
function isPositiveNumberGuard(n) { return typeof n === 'number' && Number.isFinite(n) && n > 0; }

Try / catch

try { parseArgs(process.argv); }
catch (err) { if (/must be a positive number/.test(err.message)) { console.error(err.message); printHelp(2); } else throw err; }

Prevention

When it happens

Trigger: Passing zero, a negative number, NaN/Infinity, or non-numeric text to one of the floating-point-allowed flags. Examples: `--watch-interval-seconds 0`, `--wake-grace-multiplier -1`, `--bash-timeout-seconds fast`.

Common situations: Misunderstanding units (passing 0 thinking it means 'no timeout'). A shell variable expanding to empty, which Number('')===0 fails the >0 check. Using an integer-only mindset for a flag that does accept decimals but still must be positive.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/d942667b33cec635. Report an issue: GitHub.