The published site and every signed-in workspace returned a server error. No customer data was lost, altered, or exposed: the failure was in the server bundle that renders pages, not in the database or its access policies.
Date
08-15-2026
Window
8:42 PM – 1:14 AM CT
Duration
4 hours 32 minutes
Data Impact
None — no data loss, corruption, or unauthorized access.
What Went Wrong
A markdown renderer and a browser-only charting library were reachable from a server-rendered route module. The production worker evaluates every route module at boot, so the bad import chain took down the whole bundle rather than one page. A stale cached service worker then kept serving the broken shell to browsers after the fix shipped, which is why recovery took a second publish and a cache purge.
Severity: Sev-1 — full public outage · Reported by: Owner (Joe Barnhill) after a failed page load on the published site
Step-By-Step Timeline
Every failure, diagnosis, fix, publish, and cache refresh, in the order it happened. Times are Central and elapsed markers count from the first failed request.
T+0mFailureSite Offline
Publish Completes, Server Bundle Fails To Boot
A publish finished successfully at the build step, but the production worker could not evaluate its server bundle. Every route, including the marketing home page, began returning a server error.
500 on GET / — worker boot error, no route handlers registered
Result
Public site offline. Start of the outage window.
T+9mDetectionSite Offline
Outage Confirmed From Two Independent Signals
A failed page load was reported by the owner and independently confirmed against the health endpoint from outside the network.
GET /healthz — 500 (expected 200 ok)
Result
Incident opened; investigation moved to the server boot path.
T+26mDiagnosisSite Offline
Failure Isolated To Server-Side Module Evaluation
Local development still worked because the dev server evaluates modules lazily. Reproducing against a production build surfaced the real error at boot instead of at request time.
ReferenceError: window is not defined — during route module evaluation
What Changed
Ran a production build locally and imported each route module in isolation.
Result
Two offending import chains identified in server-rendered route modules.
T+55mFixSite Offline
Markdown Renderer Moved Behind A Client-Only Boundary
The markdown renderer used by help and guide pages was imported at module scope, so the server evaluated it on boot. It now loads lazily in the browser only.
What Changed
Converted the renderer to a lazy import behind a client-only wrapper.
Result
First of two boot failures cleared in the local production build.
T+1h 20mFixSite Offline
Browser-Only Chart Library Removed From The Server Path
A dashboard chart module pulled a browser-only library into a shared utility that server-rendered routes imported. Shared values were split into a server-safe module so the heavy library stays on the client.
What Changed
Split shared constants and types out of the chart module; charts now load after hydration.
Result
Local production build booted cleanly for the first time.
T+1h 39mPublish / Cache RefreshSite Offline
First Recovery Publish
The two fixes were published together. The server came back, but browsers with a previously cached service worker still rendered a broken shell.
GET /healthz — 200 ok; hard-reloaded browsers fine, returning browsers still broken
What Changed
Published the fixed build to production.
Result
Server healthy, but returning visitors still saw the failure.
T+2h 2mDiagnosisSite Offline
Stale Service Worker Identified As The Second Failure
The offline cache was serving the pre-outage application shell and its now-missing asset URLs, so a healthy server still produced a blank page for anyone who had visited before.
Workbox: precache entry not found — cached shell references removed asset hashes
Result
Recovery required a cache-invalidating publish, not just a code fix.
T+2h 27mFixSite Offline
Service Worker Given A New Revision And Self-Retirement Path
The cache revision was bumped, oversized entries that had been silently failing to precache were dropped, and the worker now claims clients and deletes caches from older revisions on activation.
What Changed
Bumped the precache revision, reduced the precache budget, and enabled skip-waiting plus old-cache cleanup.
Result
Returning browsers now discard the broken shell on their first request.
T+2h 49mPublish / Cache RefreshSite Reachable
Second Recovery Publish And Edge Cache Purge
The new build was published and the edge cache was purged so that the HTML document and the service worker script were both refetched from origin rather than served from an intermediate cache.
What Changed
Published, then purged the cached HTML and service-worker responses.
Result
Fresh and returning browsers both loaded the working site.
T+3h 10mVerificationSite Reachable
Route-By-Route Boot Verification Added
A diagnostic endpoint was added that imports every server-rendered route module and reports any that fail to evaluate or that pull in a browser-only library — turning this class of outage into a pre-publish check instead of a post-publish surprise.
GET /routesz — all route modules evaluated, no browser-only leaks
What Changed
Added the /routesz boot probe behind a shared secret.
Result
The failure mode is now detectable before a publish goes out.
T+3h 44mVerificationSite Reachable
Signed-In Paths And Workspace Data Confirmed Intact
Sign-in, workspace switching, the ledger, invoices, and reconciliation were exercised on the published site. Record counts matched pre-outage values and access policies behaved as expected.
Result
No data loss and no cross-workspace exposure.
T+4h 32mVerificationSite Reachable
Incident Closed After A Clean Observation Window
Health checks, the route boot probe, and a post-publish smoke test all passed repeatedly with no recurrence, and the incident was closed.
Post-publish smoke test — all checks passed
Result
Service fully restored. Total outage: 4 hours 32 minutes.
What Changed Afterward
The safeguards added so this class of failure is caught before a publish reaches you.
Route Boot Probe In Every Publish
In Place
The /routesz probe runs as part of the post-publish smoke test, so a server bundle that cannot boot is caught immediately.
Cache Revision Tied To Each Build
In Place
The offline cache revision changes with every build, so a new publish can never be shadowed by an old cached shell.
Production Build Check Before Publishing
In Place
Server-side rendering is exercised against a production build, not only the development server, because the development server hides boot-time failures.
Automated External Uptime Alert
Planned
An outside monitor pinging the health endpoint on a short interval so detection does not depend on someone loading a page.
Questions about this incident, or want the same detail for a future one? See Security & Trust for how we handle notification and review, or reach us through the security contact form there.