Found while implementing #4252 (PR #4521); not fixed there — out of that card's scope, and it predates it.
What
packages/app-shell/src/console/AppContent.tsx holds the post-publish readiness re-check in missingRecheck: 'idle' | 'checking' | 'done'. It is reset to 'idle' on exactly one condition — requestedAppMissing going false:
useEffect(() => {
if (!requestedAppMissing) {
if (missingRecheck !== 'idle') setMissingRecheck('idle');
return;
}
if (missingRecheck === 'idle' && !metadataLoading && !previewDrafts) {
setMissingRecheck('checking');
Promise.resolve(refreshMetadata()).finally(() => setMissingRecheck('done'));
}
}, [requestedAppMissing, metadataLoading, previewDrafts, missingRecheck, refreshMetadata]);
Navigating from one missing app to another missing app never satisfies that condition: requestedAppMissing is true before the transition and true after it, so missingRecheck stays 'done' and the second app gets no re-check. The state is a flag about "a re-check has run", not about which app it ran for.
Why it matters
The re-check exists because "the registry can lag a beat behind a publish" — it is what makes a just-built app resolve on its own instead of flashing "App not available". An app reached second in a session (launcher → typo'd URL → the real, freshly-published app; or two attempts in a row while a build lands) does not get that grace, and shows the not-available screen with no refresh behind it. Retry still works, so the user has a way out — which is why this reads as low severity rather than a strand.
Severity note
Graded observation-class at filing time (finding, no pm:queue): the failure needs two consecutive missing apps in one mount, and the visible cost is one skipped refresh, not a wrong screen. Grade it in triage rather than trusting that line — severity judged at filing time is unreliable in both directions in this repo's history.
Related but distinct
PR #4521 hit the same shape one state over and had to fix it there, because the consequence differed: the access verdict it introduces would have shown the wrong screen (the first app's authorization denial over the second app's absence), rather than merely skipping work. That one is keyed to the app it describes and pinned by a test; missingRecheck was deliberately left as-is so the fix stayed inside #4252's surface.
Not to be confused with #4486 (MetadataProvider cache keyed by type, not org) — different layer, different cache.
Found while implementing #4252 (PR #4521); not fixed there — out of that card's scope, and it predates it.
What
packages/app-shell/src/console/AppContent.tsxholds the post-publish readiness re-check inmissingRecheck: 'idle' | 'checking' | 'done'. It is reset to'idle'on exactly one condition —requestedAppMissinggoing false:Navigating from one missing app to another missing app never satisfies that condition:
requestedAppMissingis true before the transition and true after it, somissingRecheckstays'done'and the second app gets no re-check. The state is a flag about "a re-check has run", not about which app it ran for.Why it matters
The re-check exists because "the registry can lag a beat behind a publish" — it is what makes a just-built app resolve on its own instead of flashing "App not available". An app reached second in a session (launcher → typo'd URL → the real, freshly-published app; or two attempts in a row while a build lands) does not get that grace, and shows the not-available screen with no refresh behind it. Retry still works, so the user has a way out — which is why this reads as low severity rather than a strand.
Severity note
Graded observation-class at filing time (
finding, nopm:queue): the failure needs two consecutive missing apps in one mount, and the visible cost is one skipped refresh, not a wrong screen. Grade it in triage rather than trusting that line — severity judged at filing time is unreliable in both directions in this repo's history.Related but distinct
PR #4521 hit the same shape one state over and had to fix it there, because the consequence differed: the access verdict it introduces would have shown the wrong screen (the first app's authorization denial over the second app's absence), rather than merely skipping work. That one is keyed to the app it describes and pinned by a test;
missingRecheckwas deliberately left as-is so the fix stayed inside #4252's surface.Not to be confused with #4486 (MetadataProvider cache keyed by type, not org) — different layer, different cache.