| Feed empty | Worker unreachable and GDELT empty | window.__NOVAREPORT_NEWS_DEBUG__ in the console; the Worker /health endpoint |
| Feed slow for ~60s, then recovers | Worker cooldown after two failures | Normal behavior; the Worker is retried automatically |
| 403 from the Worker | Request from a non-allowed origin | Confirm the page runs on novareport.net or an allowed preview |
| 429 from the Worker | Per-IP rate limit | Wait a minute |
| Sign-in shows "Accounts are temporarily unavailable" | No Clerk publishable key committed yet (COMMITTED_CLERK_PUBLISHABLE_KEY in src/config/backend.ts is empty) | Expected until the Clerk application exists — see Neon + Clerk cutover. News reading is unaffected |
| Console: one warning "Backend unavailable (reading cached articles)… skipping" | The Worker could not be reached, or it has no database yet (/api/news/cached answers 503 database_not_configured) | curl -s https://novareport-news-api.michelduek.workers.dev/api/health — checks.database must be ok. The app retries after 5 minutes |
| Admin page: "We could not verify your access: This feature is not available yet." | Worker has no DATABASE_URL | Set it (cutover runbook, step 1) |
| Admin page: "This account is not a NovaReport administrator." | Signed in, but the account's role in Neon is user | npm run role:grant -- user_… admin --reason "…" in workers/news-api |
/api/* answers 401 invalid_token | Expired session, or a token from another Clerk instance | Sign out and in again; check that CLERK_JWT_KEY belongs to the same instance as the committed publishable key |
| Clerk webhook deliveries fail | Wrong CLERK_WEBHOOK_SIGNING_SECRET, or the endpoint URL is not /api/webhooks/clerk | Clerk → Webhooks → endpoint → Message attempts; Cloudflare Worker logs (search the requestId) |
Console: ERR_CONNECTION_REFUSED or ERR_BLOCKED_BY_CLIENT for analytics.google.com, pagead2.googlesyndication.com, googleads.g.doubleclick.net | The visitor's ad blocker, privacy extension or filtering DNS (Pi-hole, AdGuard, NextDNS) | Not a site defect. Compare getent ahostsv4 analytics.google.com with dig +short analytics.google.com @1.1.1.1: a filtering resolver answers 0.0.0.0, which the browser reports as connection refused. In a browser profile without blockers, gtag/js and adsbygoogle.js return 200. The site keeps working either way |
429 gdelt_rate_limited from the Worker | GDELT throttles shared traffic | Transient; the feed uses GNews first and only falls back to GDELT |
Feed shows stories a few hours old; the /gnews response has X-NovaReport-Stale | GNews (or GDELT) answered 429/5xx, and the Worker served the last good answer for that feed (kept up to 48 h) | Expected while the provider is rate-limited. If it lasts, check the GNews quota (free plan: 100 requests/day) |
| Feed empty on a preview URL | Worker rejects non-allowed origins | The Worker only accepts requests from novareport.net, nova-report-net.vercel.app, Vercel preview deployments matching that project, and localhost dev ports (8080, 5173, 4173). Lovable preview URLs and other staging hosts are blocked by design. |