tinyhumansai/openhuman · error · Error

${label} must be a non-negative number

Error message

${label} must be a non-negative number

What it means

parseNonNegativeNumber() accepts any finite number >= 0 (fractions allowed) and throws with the label otherwise. In harness-cache-audit.mjs it guards --min-hit-rate, the aggregate cached/input ratio threshold in percent below which the audit exits non-zero. Non-numeric strings become NaN and fail Number.isFinite; negatives fail the < 0 check.

Source

Thrown at scripts/debug/harness-cache-audit.mjs:152

function parsePositiveInt(raw, label) {
  const value = Number(raw);
  if (!Number.isInteger(value) || value < 1)
    throw new Error(`${label} must be a positive integer`);
  return value;
}

function parseNonNegativeInt(raw, label) {
  const value = Number(raw);
  if (!Number.isInteger(value) || value < 0)
    throw new Error(`${label} must be a non-negative integer`);
  return value;
}

function parseNonNegativeNumber(raw, label) {
  const value = Number(raw);
  if (!Number.isFinite(value) || value < 0)
    throw new Error(`${label} must be a non-negative number`);
  return value;
}

function defaultOpenhumanDir() {
  return process.env.OPENHUMAN_APP_ENV === "staging"
    ? path.join(homedir(), ".openhuman-staging")
    : path.join(homedir(), ".openhuman");
}

async function defaultWorkspace() {
  if (process.env.OPENHUMAN_WORKSPACE) return process.env.OPENHUMAN_WORKSPACE;
  const openhumanDir = defaultOpenhumanDir();
  try {
    const active = await readFile(
      path.join(openhumanDir, "active_user.toml"),
      "utf8",
    );
    const match = active.match(/^\s*user_id\s*=\s*"([^"]+)"\s*$/m);

View on GitHub (pinned to a221052e0d)

Solutions

  1. Pass a plain percent number: `--min-hit-rate 20` for 20%
  2. Drop the % sign and any units
  3. Remember the unit is percent, not a 0-1 ratio
  4. Guard wrappers with a numeric regex before composing the command

Example fix

# before
node scripts/debug/harness-cache-audit.mjs --min-hit-rate 20%
# Error: --min-hit-rate must be a non-negative number

# after
node scripts/debug/harness-cache-audit.mjs --min-hit-rate 20
Defensive patterns

Strategy: validation

Validate before calling

const toNonNegativeNumber = (raw, label) => {
  const n = Number(raw);
  if (!Number.isFinite(n) || n < 0) {
    console.error(`${label} must be a number >= 0, no % or units (got: ${raw})`);
    process.exit(2);
  }
  return n;
};
const minHitRate = toNonNegativeNumber(process.env.MIN_HIT_RATE ?? "1", "--min-hit-rate");

Type guard

const isNonNegativeNumberString = (s) => /^\d+(\.\d+)?$/.test(String(s).trim());

Prevention

When it happens

Trigger: `--min-hit-rate -5`, `--min-hit-rate abc`, `--min-hit-rate 20%` (trailing % makes it NaN), `--min-hit-rate Infinity` (not finite); an unset env var interpolated as the bare text of the flag's value in a wrapper.

Common situations: Percent sign copied along with the number; comma decimal (`0,5`); intending a ratio (0.2) where a percent (20) is expected — legal but semantically off, so the audit silently passes/fails unexpectedly; wrapper variable typos.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/ec24098d0134963d. Report an issue: GitHub.