nexu-io/open-design · error · RangeError
${key} must be a non-negative finite number, got "${raw}"
Error message
${key} must be a non-negative finite number, got "${raw}" What it means
Thrown by parseNonNegativeFloat() (used by loadCritiqueConfigFromEnv for OD_CRITIQUE_SCORE_THRESHOLD) as a RangeError when the value is set but is not a finite number >= 0 (negative, NaN, Infinity, or non-numeric). ${key} is always 'OD_CRITIQUE_SCORE_THRESHOLD' in current usage; ${raw} is the offending input. Threshold is a float because panel scores are continuous.
Source
Thrown at apps/daemon/src/critique/config.ts:69
return v === 'true' || v === '1' || v === 'yes';
}
function parsePositiveInt(key: string, raw: string | undefined, fallback: number): number {
if (raw === undefined) return fallback;
const n = Number(raw);
if (!Number.isFinite(n) || !Number.isInteger(n) || n < 1) {
throw new RangeError(
`${key} must be a positive integer, got "${raw}"`,
);
}
return n;
}
function parseNonNegativeFloat(key: string, raw: string | undefined, fallback: number): number {
if (raw === undefined) return fallback;
const n = Number(raw);
if (!Number.isFinite(n) || n < 0) {
throw new RangeError(
`${key} must be a non-negative finite number, got "${raw}"`,
);
}
return n;
}
function parseFallbackPolicy(
raw: string | undefined,
fallback: CritiqueConfig['fallbackPolicy'],
): CritiqueConfig['fallbackPolicy'] {
if (raw === undefined) return fallback;
const trimmed = raw.trim();
if (FALLBACK_POLICIES.includes(trimmed as CritiqueConfig['fallbackPolicy'])) {
return trimmed as CritiqueConfig['fallbackPolicy'];
}
throw new RangeError(
`OD_CRITIQUE_FALLBACK_POLICY must be one of ${FALLBACK_POLICIES.join(', ')}, got "${raw}"`,
);View on GitHub (pinned to 5be4028344)
Solutions
- Set OD_CRITIQUE_SCORE_THRESHOLD to a non-negative finite number (e.g. 0.8, or 8 depending on scale) using a dot decimal.
- Unset it to use the default threshold from defaultCritiqueConfig().
- Ensure templated env files emit a plain numeric literal, not empty strings or localized decimals.
Example fix
# before: negative / non-numeric / locale decimal OD_CRITIQUE_SCORE_THRESHOLD=-1 OD_CRITIQUE_SCORE_THRESHOLD=0,8 # after: non-negative finite, dot decimal OD_CRITIQUE_SCORE_THRESHOLD=0.8
Defensive patterns
Strategy: validation
Validate before calling
function assertNonNegFloat(key: string, raw: string | undefined, fallback: number) {
if (raw === undefined) return fallback;
const n = Number(raw);
if (!Number.isFinite(n) || n < 0) {
throw new RangeError(`${key} must be a non-negative finite number, got "${raw}"`);
}
return n;
} Type guard
function isNonNegFloat(raw: unknown): raw is number {
return typeof raw === 'number' && Number.isFinite(raw) && raw >= 0;
} Try / catch
try { loadCritiqueConfigFromEnv(); }
catch (e) {
if (e instanceof RangeError && /non-negative/.test(e.message)) {
// fall back to defaults or fail boot
} else throw e;
} Prevention
- Use dot decimals in env values (avoid locale-specific commas).
- Validate numeric env in CI for templated configs.
- Reject empty strings and 'auto' literals before they reach Number().
When it happens
Trigger: Setting OD_CRITIQUE_SCORE_THRESHOLD to a negative number, NaN, Infinity, or a non-numeric string. e.g. OD_CRITIQUE_SCORE_THRESHOLD=-1, OD_CRITIQUE_SCORE_THRESHOLD=high.
Common situations: Operator entered a negative threshold thinking it disables the gate; a templated value injected an empty string or 'auto'; locale-related comma decimal ('0,8') parsed to NaN.
Related errors
- OD_CRITIQUE_SCORE_THRESHOLD (${scoreThreshold}) must be <= O
- ${key} must be a positive integer, got "${raw}"
- OD_CRITIQUE_FALLBACK_POLICY must be one of ${FALLBACK_POLICI
- OD_DATA_DIR is required when OD_SANDBOX_MODE is enabled
- WORKSPACE_AUTHORITY_UNAVAILABLE
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/0a7ae17c42718f03.
Report an issue: GitHub.