Skip to content

Version skew protection and ChunkLoadError recovery#368

Merged
jhodapp merged 3 commits intomainfrom
feat/stale-build-detection-and-sse-reconnect
Apr 3, 2026
Merged

Version skew protection and ChunkLoadError recovery#368
jhodapp merged 3 commits intomainfrom
feat/stale-build-detection-and-sse-reconnect

Conversation

@jhodapp
Copy link
Copy Markdown
Member

@jhodapp jhodapp commented Apr 3, 2026

Description

After a deploy, the Next.js server restarts with new chunk hashes but the browser still holds old JS bundles. This mismatch causes RSC flight data 404s and ChunkLoadErrors, which can cascade into React error #185 (maximum update depth exceeded). This PR adds two layers of protection.

GitHub Issue: Related to #366

Changes

  • Added deploymentId to next.config.mjs — Next.js built-in version skew protection that detects client/server mismatch during navigation and triggers a hard reload
  • Added GIT_COMMIT_SHA as a Docker build arg through all Dockerfile stages and the CI workflow, so deploymentId is set in production
  • Created global-error.tsx — root error boundary that catches ChunkLoadErrors (stale chunks 404ing) and auto-reloads once, with sessionStorage-based infinite loop prevention
  • Added branch workflow rule as first section in coding standards

Testing Strategy

  • 11 integration tests in __tests__/app/global-error.test.tsx covering:
    • ChunkLoadError triggers a single window.location.reload()
    • sessionStorage flag prevents infinite reload loops
    • Flag is cleared after skipping reload so next deploy can retry
    • "Failed to fetch dynamically imported module" errors are treated as chunk errors
    • Non-chunk errors show fallback UI with "Try again" button (no auto-reload)
  • global-error.tsx only activates in production builds (Next.js limitation) — E2E testing not possible in dev mode per vercel/next.js#46964
  • GIT_COMMIT_SHA defaults to undefined locally, so deploymentId is disabled in dev — no behavioral change

Concerns

  • The PR preview Docker builds happen in the backend repo's reusable workflow — GIT_COMMIT_SHA needs to be passed there separately
  • global-error.tsx cannot be E2E tested against npm run dev — only production builds. The integration tests cover the component logic thoroughly.

After a deploy, stale client JS can mismatch with the new server,
causing RSC 404s and ChunkLoadErrors. This adds Next.js built-in
deploymentId protection (triggers hard reload on navigation mismatch)
and a global-error.tsx boundary that catches ChunkLoadErrors with
sessionStorage-based infinite loop prevention.
@jhodapp jhodapp self-assigned this Apr 3, 2026
@jhodapp jhodapp changed the title feat: version skew protection and ChunkLoadError recovery Version skew protection and ChunkLoadError recovery Apr 3, 2026
@jhodapp jhodapp added the enhancement Improves existing functionality or feature label Apr 3, 2026
@jhodapp jhodapp added this to the 1.0.0-beta3 milestone Apr 3, 2026
@jhodapp jhodapp marked this pull request as ready for review April 3, 2026 22:48
@jhodapp jhodapp requested review from calebbourg and lmcdonough April 3, 2026 22:49
@jhodapp jhodapp merged commit c4b2daa into main Apr 3, 2026
6 checks passed
@jhodapp jhodapp deleted the feat/stale-build-detection-and-sse-reconnect branch April 3, 2026 23:31
@github-project-automation github-project-automation bot moved this from Review to ✅ Done in Refactor Coaching Platform Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Improves existing functionality or feature

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

1 participant