koala73/worldmonitor · error · Error
${DEVELOPMENTS_COVERAGE_RATIO_ENV} must be a ratio in (0, 1]
Error message
${DEVELOPMENTS_COVERAGE_RATIO_ENV} must be a ratio in (0, 1], got ${JSON.stringify(raw)} What it means
resolveDevelopmentsCoverageRatioOverride reads the CRAWLABLE_DEVELOPMENTS_COVERAGE_RATIO env var to let operators temporarily lower the developments-coverage floor. The value must be a finite number in (0, 1]. Anything else (non-numeric, zero, negative, or > 1) throws this error immediately during build configuration.
Solutions
- Fix the env var to a valid ratio: a decimal number greater than 0 and at most 1 (e.g. 0.8).
- Unset the variable entirely to use the built-in default floors.
- If you meant a percentage, divide by 100 (80% -> 0.8).
- Check CI/secret configuration for quoting or locale issues that corrupt the value.
Example fix
// before CRAWLABLE_DEVELOPMENTS_COVERAGE_RATIO=0,8 // after CRAWLABLE_DEVELOPMENTS_COVERAGE_RATIO=0.8
Defensive patterns
Strategy: validation
Validate before calling
const raw = process.env.CRAWLABLE_DEVELOPMENTS_COVERAGE_RATIO;
const r = Number(raw);
if (raw && !(Number.isFinite(r) && r > 0 && r <= 1)) throw new Error('ratio must be in (0,1]'); Try / catch
try { ratio = resolveDevelopmentsCoverageRatioOverride(); } catch (e) { console.error('Bad coverage ratio env:', e.message); process.exit(2); } Prevention
- Always express the override as a decimal ratio, never a percentage or comma-decimal.
- Document valid examples (0.5, 0.8) in CI secret names/comments.
- Unset the var to fall back to defaults.
When it happens
Trigger: Setting CRAWLABLE_DEVELOPMENTS_COVERAGE_RATIO to a non-numeric string (e.g. '0,8' with a comma), 0, a negative number, a value greater than 1, or any non-empty malformed value in the environment before running the build.
Common situations: Typos in CI secrets ('80%' instead of '0.8'); locale-formatted decimals with commas; someone setting a percentage (2 for 2%) instead of a ratio.
Understand the failure class
Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.
Related errors
- MCP_PRO_GRANT_HMAC_SECRET is not set
- Redis not configured
- ${label} HTTP ${status} (${billingCode})
- Desktop authentication failed
- Webhook URL must not point to a private/local address
AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15).
Data as JSON: /api/errors/89ed2259854d2482.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/build-crawlable-corpus.mjs:3645
// protects fails is no gate (review of #7748). Not 100%: no article pool
// names every country every week, and a floor the weekly refresh cannot
// clear is the #7615 mistake again.
export const MIN_DEVELOPMENTS_COVERAGE_RATIO_WITH_COUNTRY_INDEX = 0.6;
// Operator override for the floor. A failed floor throws away the week's
// capture (the workflow verifies before it opens the PR), so a measured-but-
// lower week — the first freeze after the materializer redeploys, an index
// outage that morning — needs a way to publish without a code change:
// `workflow_dispatch` with `developments_coverage_ratio`, which the workflow
// passes through this variable. A malformed value throws rather than
// silently keeping the default (a typo must not look like "no override").
export const DEVELOPMENTS_COVERAGE_RATIO_ENV = 'CRAWLABLE_DEVELOPMENTS_COVERAGE_RATIO';
export function resolveDevelopmentsCoverageRatioOverride(env = process.env) {
const raw = String(env?.[DEVELOPMENTS_COVERAGE_RATIO_ENV] ?? '').trim();
if (!raw) return null;
const ratio = Number(raw);
if (!Number.isFinite(ratio) || ratio <= 0 || ratio > 1) {
throw new Error(`${DEVELOPMENTS_COVERAGE_RATIO_ENV} must be a ratio in (0, 1], got ${JSON.stringify(raw)}`);
}
return ratio;
}
// Pipeline tripwire decision (#7615, retuned in #7620 follow-up), exported for
// tests: the per-page guard proves frozen items render; this proves the capture
// did not collapse. `countryIndexAttempted` is the snapshot's own declaration
// (it carries coverage.developmentsCountryIndex), so a snapshot frozen before
// the index existed keeps the collapse floor.
export function assertDevelopmentsCoverage({
carriesDevelopments,
developmentsPageCount,
indexedCountryPageCount,
countryIndexAttempted = false,
ratioOverride = null,
}) {
if (!carriesDevelopments) return;
const ratio = ratioOverrideView on GitHub (pinned to 7d06c8633d)