fix(seed): don't crash seed-conflict-intel when ACLED creds are absent#5126
Conversation
#5106 made a *missing* ACLED credential a hard, non-retryable throw. But ACLED has never been provisioned in production (the seed-conflict-intel Railway service has only an empty VITE_ACLED_ACCESS_TOKEN, which the seed doesn't even read), so the seed — which had run fine in its long-standing auxiliary-only mode (#1651/#2288) — began crashing gracefully (exit 75) on every ~30-min cron tick, firing a "Deploy Crashed!" alert each time (GRACEFUL·CHRONIC). Distinguish the two cases in fetchAll(): - ACLED creds ABSENT (fetchAcledEvents → null → fulfilled): publish the auxiliary feeds (already written) + an empty ACLED payload and exit 0, as before #5106. No data lost, no alert-fatigue. - ACLED creds PRESENT but display fetch failed (rejected): keep #5106's guard — refuse to let auxiliary feeds silently mask the broken primary feed; throw (retryable unless the source marked it non-retryable). Regression guards added in tests/acled-resolution-feed-seed.test.mjs for both branches. Claude-Session: https://claude.ai/code/session_0199ZmFiQztqqHdAdptCq5K8
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR fixes a chronic graceful crash in
Confidence Score: 5/5Safe to merge — the fix directly resolves a production crash loop with a minimal, targeted change, and auxiliary feeds continue to be written before the early return path. The two-branch distinction in fetchAll() correctly maps fulfilled-with-null to the no-credentials case and rejected to the fetch-failure case. The early return of an empty-but-valid payload passes the existing validate() and declareRecords() contracts, auxiliary keys are already written before the guard, and both new test cases fail against the pre-fix code and pass after. No files require special attention. Important Files Changed
Reviews (1): Last reviewed commit: "fix(seed): don't crash seed-conflict-int..." | Re-trigger Greptile |
Problem — chronic graceful crash, surfaced by
/diagnose-railway-seedersseed-conflict-intelwas classified GRACEFUL·CHRONIC: it crashed gracefully (exit 75, one "Deploy Crashed!" alert each) on every ~30-min cron tick — 3 crashes in the hour before diagnosis (15:02 / 15:30 / 16:00 UTC). Same evidence each run:Root cause
ACLED_EMAIL/ACLED_PASSWORDorACLED_ACCESS_TOKEN(scripts/seed-conflict-intel.mjs:40-61). No valid ACLED credential exists in production — the Railway service has onlyVITE_ACLED_ACCESS_TOKENset to an empty string (and the seed doesn't read thatVITE_-prefixed name).acledIntelhas always been empty.return ac || {events:[]}into a hard, non-retryablethrowfor any missingac— treating "ACLED absent" (intended) the same as "primary feed broken" (alarming). A seed that had run fine for months began crashing every tick. Only alert-fatigue + wasted compute resulted; no data was lost (auxiliary keys still written).Fix
Distinguish the two cases in
fetchAll():fetchAcledEvents→null→ settledfulfilled): log + return an empty ACLED payload and exit 0, restoring the pre-fix(forecast): fail ACLED seed when primary feed is unavailable #5106 auxiliary-only behavior.rejected): keep fix(forecast): fail ACLED seed when primary feed is unavailable #5106's genuine value — refuse to let auxiliary feeds silently mask a broken primary feed;throw(retryable unless the source marked it non-retryable).This stops the crash immediately without needing ACLED credentials. (Provisioning a real ACLED token to actually populate the empty
acledIntelfeed is a separate, deferred ops task.)Tests
tests/acled-resolution-feed-seed.test.mjs— the #5106 contract block is replaced with two guards (one per branch). Both fail against the pre-fix code and pass after. Full file +tests/forecast-resolution-eval.test.mjs: 30 pass / 0 fail.node --check+biome lintclean.🤖 Generated with Claude Code
https://claude.ai/code/session_0199ZmFiQztqqHdAdptCq5K8