nexu-io/open-design · error · RangeError
${key} must be a positive integer, got "${raw}"
Error message
${key} must be a positive integer, got "${raw}" What it means
Thrown by parsePositiveInt() (used by loadCritiqueConfigFromEnv) as a RangeError when one of the OD_CRITIQUE_* integer env vars (OD_CRITIQUE_MAX_ROUNDS, OD_CRITIQUE_SCORE_SCALE, OD_CRITIQUE_PER_ROUND_TIMEOUT_MS, OD_CRITIQUE_TOTAL_TIMEOUT_MS, OD_CRITIQUE_PARSER_MAX_BLOCK_BYTES) is set but is not a finite integer >= 1. ${key} names exactly which env var failed and ${raw} shows the offending value.
Source
Thrown at apps/daemon/src/critique/config.ts:58
fallbackPolicy,
};
}
// ---------------------------------------------------------------------------
// Parsing helpers
// ---------------------------------------------------------------------------
function parseEnabled(raw: string | undefined, fallback: boolean): boolean {
if (raw === undefined) return fallback;
const v = raw.trim().toLowerCase();
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(View on GitHub (pinned to 5be4028344)
Solutions
- Set the named var to a positive integer (>= 1) with no units — e.g. OD_CRITIQUE_MAX_ROUNDS=3, OD_CRITIQUE_PER_ROUND_TIMEOUT_MS=60000.
- Unset the var to fall back to defaultCritiqueConfig().
- Strip units/whitespace from templated env values before they reach the process.
Example fix
# before: zero / float / non-numeric OD_CRITIQUE_MAX_ROUNDS=0 OD_CRITIQUE_PER_ROUND_TIMEOUT_MS=2.5s # after: positive integers, no units OD_CRITIQUE_MAX_ROUNDS=3 OD_CRITIQUE_PER_ROUND_TIMEOUT_MS=60000
Defensive patterns
Strategy: validation
Validate before calling
function assertPositiveInt(key: string, raw: string | undefined, fallback: 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;
} Type guard
function isPositiveInt(raw: unknown): raw is number {
return typeof raw === 'number' && Number.isFinite(raw) && Number.isInteger(raw) && raw >= 1;
} Try / catch
try { loadCritiqueConfigFromEnv(); }
catch (e) {
if (e instanceof RangeError) { console.error('critique config invalid', e.message); process.exit(1); }
throw e;
} Prevention
- Lint env files for numeric values before deployment.
- Strip units/whitespace from templated values before they reach the process.
- Treat critique boot errors as fatal: fix the env, do not catch-and-continue.
When it happens
Trigger: Setting any of the listed OD_CRITIQUE_* integer vars to zero, a negative, a float, NaN/Infinity, or a non-numeric string. e.g. OD_CRITIQUE_MAX_ROUNDS=0, OD_CRITIQUE_PER_ROUND_TIMEOUT_MS=2.5, OD_CRITIQUE_TOTAL_TIMEOUT_MS=abc.
Common situations: Operator set a timeout to 0 thinking it disables it; trailing whitespace/unit ('1000ms'); a float slipped in via a templated env file; copy-paste from a doc that used a different unit.
Related errors
- OD_CRITIQUE_SCORE_THRESHOLD (${scoreThreshold}) must be <= O
- ${key} must be a non-negative finite number, 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/1db22d67bcb4a026.
Report an issue: GitHub.