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.tomland hand-rolledcurl -X DELETErequests 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.devresolved 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
Deleteaction on themirrorhabit.pages.devzone, - actor
varunpaherwar@proton.me(me), - timestamped 17:39 UTC — two minutes after that session’s wrangler
project list/deployment listcalls (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
- No dedicated “purge edge cache” CLI. Wrangler has no Pages cache-purge command, so the fallback was a raw API call with guessed endpoints.
- Raw
DELETEon a project resource is dangerous — some paths underpages/projects/<name>behave like the delete, andDELETEsucceeded with a plausible200. - Reading production tokens into a session removes every guardrail — no scoped-token errors, no confirmation prompts, and secrets end up in transcript files.
- 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.devis 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.deveverywhere (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
catthe 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.
DELETEon anything underpages/projects/<name>gets a second look before sending — or better, usewrangler 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.”