Found while implementing #5533 (its PR); deliberately left out of that PR's scope, which fenced MarketplacePage.tsx as read-only.
Claim
MarketplacePage — the marketplace catalog page — orders its early returns so that the admin check runs before the runtime check:
if(!isAdmin)return<MarketplaceAccessDenied/>;// ~line 200if(!marketplaceEnabled)return<MarketplaceDisabled/>;// ~line 203
So on a runtime with no marketplace at all (features.marketplace: false, an OS_CLOUD_URL=off deployment), an unprivileged viewer is told they lack permission for a surface that exists for nobody.
Why this is worth closing
It is the same misdirection class as #5533 — the page reports the wrong kind of answer — but in the opposite direction and for non-admins only:
| viewer | catalog page today | detail page after #5533 |
|---|
| admin, marketplace off | "turned off" ✅ | "turned off" ✅ |
| non-admin, marketplace off | "access denied" ❌ | "turned off" ✅ |
So after #5533 lands, the two sibling pages still disagree for non-admins — which is exactly the invariant #5504 and #5533 were closing. "Access denied" invites the viewer to go ask an administrator for a permission that would not help them, because there is nothing behind the door on this deployment.
Not claimed
That the ordering is wrong in general. On a runtime that does have a marketplace, admin-before-anything is correct and should stay. The defect is only that the disabled state is unreachable for a non-admin.
Shape of the fix
A two-line reorder in MarketplacePage.tsx: the runtime check answers first, because "this deployment has no marketplace" is true regardless of who is asking. #5533's PR did not touch it — MarketplacePage.tsx was explicitly read-only for that card, and reordering it changes what non-admins see, which wants its own measurement.
Refs
Generated by Claude Code
Generated by Claude Code
Found while implementing #5533 (its PR); deliberately left out of that PR's scope, which fenced
MarketplacePage.tsxas read-only.Claim
MarketplacePage— the marketplace catalog page — orders its early returns so that the admin check runs before the runtime check:So on a runtime with no marketplace at all (
features.marketplace: false, anOS_CLOUD_URL=offdeployment), an unprivileged viewer is told they lack permission for a surface that exists for nobody.Why this is worth closing
It is the same misdirection class as #5533 — the page reports the wrong kind of answer — but in the opposite direction and for non-admins only:
So after #5533 lands, the two sibling pages still disagree for non-admins — which is exactly the invariant #5504 and #5533 were closing. "Access denied" invites the viewer to go ask an administrator for a permission that would not help them, because there is nothing behind the door on this deployment.
Not claimed
That the ordering is wrong in general. On a runtime that does have a marketplace, admin-before-anything is correct and should stay. The defect is only that the disabled state is unreachable for a non-admin.
Shape of the fix
A two-line reorder in
MarketplacePage.tsx: the runtime check answers first, because "this deployment has no marketplace" is true regardless of who is asking. #5533's PR did not touch it —MarketplacePage.tsxwas explicitly read-only for that card, and reordering it changes what non-admins see, which wants its own measurement.Refs
OS_CLOUD_URL=offrenders the marketplace as a red load-failure with wrong guidance, and the home page still promotes the marketplace entry #5504 / PR Console: OS_CLOUD_URL=off is a disabled state, not a red load failure #5517 (the original catalog-page disabled state)Generated by Claude Code
Generated by Claude Code