different-ai/openwork · error · Error
Failed to grant access (${response.status}).
Error message
Failed to grant access (${response.status}). What it means
Thrown by useGrantMarketplaceAccess in marketplace-data.tsx when POST /v1/marketplaces/{marketplaceId}/access (15s timeout) returns non-ok. getRequestError (den-flow.ts:527) turns a 403 {error:'reauth'} payload into ReauthRequiredError and otherwise yields the server `error` message or the fallback "Failed to grant access (<status>).".
Source
Thrown at ee/apps/den-web/app/(den)/dashboard/_components/marketplace-data.tsx:299
body:
| { orgWide: true; role?: MarketplaceAccessRole }
| { teamId: string; role?: MarketplaceAccessRole }
| { orgMembershipId: string; role?: MarketplaceAccessRole };
}) => {
await runReauthableAction("grant-marketplace-access", async () => {
const body = {
role: input.body.role ?? "viewer",
...("orgWide" in input.body ? { orgWide: true } : {}),
...("teamId" in input.body ? { teamId: input.body.teamId } : {}),
...("orgMembershipId" in input.body ? { orgMembershipId: input.body.orgMembershipId } : {}),
};
const { response, payload } = await requestJson(
`/v1/marketplaces/${encodeURIComponent(input.marketplaceId)}/access`,
{ method: "POST", body: JSON.stringify(body) },
15000,
);
if (!response.ok) {
throw getRequestError(payload, response, `Failed to grant access (${response.status}).`);
}
});
return input.marketplaceId;
},
onSuccess: (marketplaceId) => {
queryClient.invalidateQueries({ queryKey: marketplaceQueryKeys.access(marketplaceId) });
queryClient.invalidateQueries({ queryKey: marketplaceQueryKeys.resolved(marketplaceId) });
},
});
}
export function useRevokeMarketplaceAccess() {
const queryClient = useQueryClient();
const { runReauthableAction } = useOrgDashboard();
return useMutation({
mutationFn: async (input: { marketplaceId: string; grantId: string }) => {
await runReauthableAction("revoke-marketplace-access", async () => {View on GitHub (pinned to 2b7df46e8a)
Solutions
- On 409, treat as success: the grant already exists — invalidate marketplaceQueryKeys.access(marketplaceId) and update the UI.
- On 404, refresh the marketplace and member lists; the marketplace or grantee is gone.
- For 403, confirm admin/owner role and complete reauth when isReauthRequiredError(error) is true.
- On 429, check the org plan/seat limits before retrying the grant.
Example fix
// before
if (!response.ok) {
throw getRequestError(payload, response, `Failed to grant access (${response.status}).`);
}
// after
if (!response.ok) {
if (response.status === 409) return input.marketplaceId; // already granted
throw getRequestError(payload, response, `Failed to grant access (${response.status}).`);
} Defensive patterns
Strategy: try-catch
Validate before calling
// before granting
if (!marketplaceId) throw new Error("marketplaceId is required.");
if (!granteeIds.length) throw new Error("Select at least one member or team.");
const missing = granteeIds.filter((id) => !activeMembers.some((m) => m.id === id));
if (missing.length) throw new Error(`Unknown grantee(s): ${missing.join(", ")}`); Type guard
function isReauthError(e: unknown): e is ReauthRequiredError {
return e instanceof ReauthRequiredError;
} Try / catch
try {
await grantMutation.mutateAsync({ marketplaceId, ...body });
} catch (error) {
if (isReauthError(error)) { startReauth(); return; }
if (/\(409\)/.test(error.message)) { await queryClient.invalidateQueries(marketplaceQueryKeys.access(marketplaceId)); return; }
showToast(error.message);
} Prevention
- Filter out already-granted members in the share dialog to prevent 409s.
- Refresh the member list before granting to avoid grants to removed users (404).
- Gate the grant UI on owner/admin role.
- Invalidate marketplaceQueryKeys.access after any grant attempt, success or conflict.
When it happens
Trigger: Granting a member/team access to a private marketplace returns non-ok: 401/403 (caller is not an org owner/admin or session expired), 404 (marketplace id or grantee id does not exist), 409 (access already granted), 422 (invalid grantee or body), 429 (plan/seat limits on marketplace access), 5xx, or the 15s timeout.
Common situations: Granting to a user removed from the org; duplicating a grant from double-click; non-admin opening the marketplace share dialog; grant body missing required fields after a marketplace schema change on the server.
Related errors
- Failed to revoke access (${response.status}).
- Failed to create collection (${response.status}).
- Failed to update collection (${response.status}).
- Failed to delete collection (${response.status}).
- invalid_marketplace_payload
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/8cf9579ee3211c8b.
Report an issue: GitHub.