Skip to content

Marketplace catalog page tells a NON-ADMIN "access denied" on a runtime that has no marketplace at all #5557

Description

@claude

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:

viewercatalog page todaydetail 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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatched

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions