🐛 Fix stale chunk errors after deploy + AI Missions navbar button#4336
🐛 Fix stale chunk errors after deploy + AI Missions navbar button#4336clubanderson merged 1 commit intomainfrom
Conversation
Chunk error fixes (#4313): - Reduce auto-reload cooldown from 30s to 5s across all handlers - Expand error pattern matching to cover Failed to fetch, NetworkError, and Unexpected token '<' (HTML returned for missing chunks) - Add app-build-id meta tag injected at build time with commit hash - Add proactive stale-HTML detection that checks on tab visibility change and every 2 minutes, reloading if server has a newer build - Update chunk error tests for new patterns and throttle values AI Missions navbar button (#4287): - Add Sparkles-icon "AI Missions" button to navbar (lg+ breakpoint) - Button opens the missions sidebar and shows attention badge count - Also add button to overflow menu for narrower viewports - Button auto-hides when sidebar is already open Fixes #4313, Fixes #4287 Signed-off-by: Andrew Anderson <andy@clubanderson.com>
✅ Deploy Preview for kubestellarconsole ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
👋 Hey @clubanderson — thanks for opening this PR!
This is an automated message. |
There was a problem hiding this comment.
Pull request overview
This PR addresses two console UX/reliability issues: improving recovery from stale Vite chunk references after deploys (#4313) and making the AI Missions sidebar easier to access via the navbar (#4287).
Changes:
- Added build-stamp metadata + proactive stale-HTML detection that reloads when the server build is newer.
- Expanded chunk-load error pattern detection and reduced auto-reload throttles from 30s to 5s.
- Added an “AI Missions” navbar button (desktop + overflow) with an attention badge for missions needing input.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| web/index.html | Adds app-build-id meta tag placeholder used to detect stale HTML after deploys. |
| web/vite.config.ts | Adds inject-build-id plugin to stamp the HTML meta tag with the current commit hash. |
| web/src/main.tsx | Reduces vite:preloadError cooldown and adds proactive stale-HTML polling/visibility checks. |
| web/src/lib/chunkErrors.ts | Adds additional message patterns for chunk-load detection. |
| web/src/lib/analytics.ts | Lowers global chunk reload throttle to 5s to match boundary behavior. |
| web/src/components/ChunkErrorBoundary.tsx | Lowers reload throttle to 5s. |
| web/src/components/layout/navbar/Navbar.tsx | Adds AI Missions button (desktop + overflow) and attention count badge. |
| web/src/lib/tests/chunkErrors.test.ts | Adds tests for new chunk error patterns. |
| web/src/lib/tests/analytics.test.ts | Updates throttle-related test values to match the new 5s throttle. |
| // Lazy-load SearchDropdown — it imports useSearchIndex which pulls in 5 MCP | ||
| // modules (~135 KB). The search bar appears after the chunk loads (near-instant). | ||
| const SearchDropdown = lazy(() => | ||
| import('./SearchDropdown').then(m => ({ default: m.SearchDropdown })) | ||
| ) | ||
|
|
||
| // Lazy-load AgentSelector — agent UI components (~41 KB) are only needed | ||
| // when a local kc-agent is available (never on console.kubestellar.io). | ||
| const AgentSelector = lazy(() => | ||
| import('../../agent/AgentSelector').then(m => ({ default: m.AgentSelector })) | ||
| ) | ||
| import { useMissions } from '../../../hooks/useMissions' | ||
| import { TokenUsageWidget } from './TokenUsageWidget' |
There was a problem hiding this comment.
import { useMissions } ... is placed after executable statements (const SearchDropdown / const AgentSelector). ES modules require all import declarations to appear before other statements, so this will fail to parse/compile. Move the useMissions import up with the other imports at the top of the file (before the lazy-loaded const declarations).
| msg.includes('Importing a module script failed') || | ||
| // safeLazy() throws this when a named export is missing from a stale chunk | ||
| msg.includes('chunk may be stale') | ||
| msg.includes('chunk may be stale') || | ||
| // Generic fetch failure — often occurs when a chunk 404s on the CDN | ||
| msg.includes('Failed to fetch') || | ||
| // Network error variant seen in Firefox for missing chunks | ||
| msg.includes('NetworkError when attempting to fetch resource') || | ||
| // Chrome: TypeError when dynamic import() receives a non-JS response (e.g. 404 HTML) | ||
| msg.includes("Unexpected token '<'") |
There was a problem hiding this comment.
isChunkLoadMessage is used by the global unhandledrejection/error handlers to decide whether to auto-reload (see tryChunkReloadRecovery). Matching the plain substring "Failed to fetch" is very broad and can also occur for ordinary API/network failures (offline, CORS, backend down), which could trigger disruptive auto-reloads unrelated to stale chunks. Consider narrowing this pattern (e.g., require dynamic-import specific context like dynamically imported module or a chunk path) so non-chunk fetch errors don’t cause reloads.
🔄 Auto-Applying Copilot Code ReviewCopilot code review found 0 code suggestion(s) and 2 general comment(s). Also address these general comments:
Push all fixes in a single commit. Run Auto-generated by copilot-review-apply workflow. |
|
/lgtm |
|
@clubanderson: you cannot LGTM your own PR. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: clubanderson The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
Thank you for your contribution! Your PR has been merged. Check out what's new:
Stay connected: Slack #kubestellar-dev | Multi-Cluster Survey |
Summary
Failed to fetch, FirefoxNetworkError, andUnexpected token '<'(HTML returned for missing chunks). Added proactive stale-HTML detection viaapp-build-idmeta tag + visibility/interval checks that auto-reload when the server has a newer build.Fixes #4313, Fixes #4287
Changes
web/index.html<meta name="app-build-id">tag for stale-HTML detectionweb/vite.config.tsinject-build-idplugin to replace placeholder with commit hash at build timeweb/src/main.tsxweb/src/lib/chunkErrors.tsFailed to fetch,NetworkError,Unexpected token '<'web/src/lib/analytics.tsGLOBAL_RELOAD_THROTTLE_MSfrom 30s to 5sweb/src/components/ChunkErrorBoundary.tsxRELOAD_THROTTLE_MSfrom 30s to 5sweb/src/components/layout/navbar/Navbar.tsxweb/src/lib/__tests__/chunkErrors.test.tsweb/src/lib/__tests__/analytics.test.tsTest plan
npm run build)vitest run chunkErrors.test.ts)