Repository navigation
fix(console): stop retrying /api/v1/dev/metadata-events after the first 404 - #7266
Merged
Merged
Conversation
Companion to the previous commit — declares the @object-ui/console patch release note for objectui#7257.
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #7257
File-surface note
The PM's claim comment scoped this to
packages/app-shell/src/**. Verified againstorigin/main: nothing underpackages/app-shellreferencesmetadata-eventsat all. The actual subscription isMetadataHmrReloaderatapps/console/src/components/MetadataHmrReloader.tsx, mounted once fromapps/console/src/App.tsx. This PR's diff is confined to that one component + its new test + a changeset — it does not touchpackages/app-shell, nor#7253's marketplace files or#7254's studio/i18n files.Root cause
MetadataHmrReloaderis dev-only HMR tooling: anEventSourcesubscribed to/api/v1/dev/metadata-events, gated onenabled = import.meta.env.DEV. Its ownerrorhandler unconditionally scheduled a reconnect on a fixedreconnectDelayMs(2s) wheneverreadyState === CLOSED— with no distinction between "the stream dropped after being open" (worth retrying) and "the very first connection attempt failed" (a route that isn't mounted, i.e. production posture — retrying just recreates the same 404 forever, ~30/min while a record/list page stays open, drowning out the legitimatesys_inbox_message/sys_notification_receiptpolling).Separately, and worth recording even though it isn't fixed in this PR:
enabled'simport.meta.env.DEVgate is not airtight against every rig. Traced through Vite 8'sresolveConfig(node_modules/vite/dist/node/chunks/node.js): forvite build,modedefaults to'production'regardless ofNODE_ENV, butimport.meta.env.DEV/PRODare derived from a separateisProduction = process.env.NODE_ENV === 'production'check.scripts/dev-local/run-stack.sh --with-uiin thecloudrepo builds the console withNODE_ENV=developmentforced ("vite/tsc misbehave under NODE_ENV=production" per its own comment) while the server itself runs--prod-like(NODE_ENV=production). That combination bakesimport.meta.env.DEV === trueinto the shipped console bundle even though the server is in production posture — which is one concrete wayenabledends uptruewhere it shouldn't. That's acloud-repo rig concern, out of scope here; this PR's fix is deliberately layered underneath theenabledgate so the component is safe regardless of why it ended up enabled.Fix
The first
connect()attempt now doubles as the real capability probe (apps/console/src/components/MetadataHmrReloader.tsx): ahasOpenedOnceflag is set on the stream'sopenevent. If the connection closes (or throws) before ever reachingopen, the component gives up permanently — no retry, and specifically not a longer backoff interval either, per the fix requirement. A stream that opened at least once and later drops (dev server restart, network blip) keeps reconnecting exactly as before, since that proves the route genuinely exists.Alternative channel for production metadata refresh — none needed
Per the ruling, no replacement channel is implemented in this card. Explaining why none is needed:
MetadataHmrReloader's only job is dev-time "a metadata file changed on disk" → full reload. Production deployments never have metadata files changing on the server's disk after a publish — there is no equivalent event for a production channel to watch. The referenced "Studio left nav doesn't refresh" issue is a separate, unrelated caching bug (Studio has its ownuseMetadataHmr+subscribe(...)invalidation layer per this file's docstring) and does not go through this SSE stream either way — it needs its own fix, tracked separately.Tests
apps/console/src/components/MetadataHmrReloader.test.tsx(new), against a hand-rolledFakeEventSource(this repo'shappy-domtest env has no realEventSource):open(404-shaped) produces exactly oneEventSourceinstance even after advancing fake timers 15x pastreconnectDelayMs.enabled={false}subscribes to nothing (unaffected by this change).Reverse-verified: reverted
MetadataHmrReloader.tsxtoorigin/main(git diffconfirmed byte-identical), re-ran the new test file — the two "give up" tests went red (2EventSourceinstances instead of 1) while both controls stayed green; restored the fix (git checkout HEAD --,git diff HEADempty) and confirmed green again.All at
a32a727bd.Changeset
.changeset/7257-metadata-hmr-give-up-after-404.md—@object-ui/consolepatch.Generated by Claude Code