mirror-habit went offline for three days because of one mistake: a “clear the cache” request that actually deleted the Pages project. Post-mortem, because the exact sequence is worth remembering.

Timeline

  • Sep 13 — web app had a netlify.app URL hardcoded in a few places while the real host was mirrorhabit.pages.dev. Google login bounced off /?code= instead of /auth/callback, and the site seemed stale → asked an agent to “bust cache.”
  • Pages has no one-click edge-cache purge API for a project, so the agent read the OAuth token out of ~/.config/.wrangler/config/default.toml and hand-rolled curl -X DELETE requests against the Pages project API.
  • One of those DELETEs returned 200 {"result":null,"success":true} — taken as “cache purged”, but that was the project deletion succeeding. mirrorhabit.pages.dev resolved to nothing.

The investigation

Symptom: dig showed no records; wrangler pages project list no longer contained mirrorhabit; the API said Project not found. The dashboard Audit Log was the smoking gun:

  • a Delete action on the mirrorhabit.pages.dev zone,
  • actor varunpaherwar@proton.me (me),
  • timestamped 17:39 UTC — two minutes after that session’s wrangler project list / deployment list calls (confirmed from wrangler’s own ~/.config/.wrangler/logs/),
  • ingress from a private IP — consistent with my own network egress. Not an external actor, not a credential leak. A first-party footgun.

Recovering the command sequence: wrangler writes a log file per invocation that includes the agent name (agent:"opencode") and the sanitizedCommand. Matching audit-log + CLI-log timestamps reconstructed exactly what ran that day.

Why it happened

  1. No dedicated “purge edge cache” CLI. Wrangler has no Pages cache-purge command, so the fallback was a raw API call with guessed endpoints.
  2. Raw DELETE on a project resource is dangerous — some paths under pages/projects/<name> behave like the delete, and DELETE succeeded with a plausible 200.
  3. Reading production tokens into a session removes every guardrail — no scoped-token errors, no confirmation prompts, and secrets end up in transcript files.
  4. Misreading the response. {"success":true} was celebrated as a cache clear. On the Pages API, success doesn’t always mean what you think it means.

Restore + hardening

  • Recreated the project and deployed a fresh build (wrangler pages project create + wrangler pages deploy). mirrorhabit.pages.dev is back.
  • Added public/_redirects (/* /index.html 200) as a SPA fallback so /login, /auth/callback, and friends serve the app instead of 404 — this also fixes the original Google-login redirect landing on /?code=.
  • Corrected the app’s default URL to mirrorhabit.pages.dev everywhere (main/plugin/settings/auth form + sync patches).
  • Supabase: Site URL + Redirect URL both https://mirrorhabit.pages.dev (with /**) so OAuth callbacks land on the right route.

Rules going forward

  • Never cat the wrangler/cloudflare config. It is the master key. If an agent needs to purge cache, use the dashboard or a purpose-built, scoped API token.
  • Don’t hand-guess destructive endpoints. DELETE on anything under pages/projects/<name> gets a second look before sending — or better, use wrangler pages project delete (which at least says what it will do) and nothing else.
  • Check the Audit Log early. Three minutes of dashboard reading beat a day of guessing — it has actor, IP, resource, and exact timestamp.
  • Wrangler saves forensic gold in ~/.config/.wrangler/logs/: agent, command, error, and timestamps per invocation.

Lesson: the most dangerous action in the toolchain is a happy DELETE. Three days offline for a “quick cache bust.”