different-ai/openwork · error
Failed to revoke dashboard access (${response.status}).
Error message
Failed to revoke dashboard access (${response.status}). What it means
Thrown by useRevokeDashboardAccess when DELETE /v1/dashboards/:id/access/:grantId returns neither 204 nor ok. Like the sibling delete mutation, non-204 success bodies are tolerated; anything else non-ok raises this error with the status in the message.
Source
Thrown at ee/apps/den-web/app/(den)/dashboard/_components/org-dashboards-data.tsx:359
queryClient.invalidateQueries({ queryKey: orgDashboardsQueryKeys.access(organizationId, dashboardId) });
},
});
}
export function useRevokeDashboardAccess() {
const queryClient = useQueryClient();
const { orgContext, runReauthableAction } = useOrgDashboard();
const organizationId = orgContext?.organization.id ?? "";
return useMutation({
mutationFn: async (input: { dashboardId: string; grantId: string }) => {
await runReauthableAction("revoke-dashboard-access", async () => {
const { response, payload } = await requestJson(
`/v1/dashboards/${encodeURIComponent(input.dashboardId)}/access/${encodeURIComponent(input.grantId)}`,
{ method: "DELETE" },
15000,
);
if (response.status !== 204 && !response.ok) {
throw getRequestError(payload, response, `Failed to revoke dashboard access (${response.status}).`);
}
});
return input.dashboardId;
},
onSuccess: (dashboardId) => {
queryClient.invalidateQueries({ queryKey: orgDashboardsQueryKeys.access(organizationId, dashboardId) });
},
});
}
/** A flat catalog containing only connections that expose launchable MCP Apps. */
export function useConnectionMcpAppCatalog(connections: Array<{ id: string; name: string }>) {
const { orgContext } = useOrgDashboard();
const organizationId = orgContext?.organization.id ?? "";
return useQueries({
queries: connections.map((connection) => ({
enabled: Boolean(organizationId),
queryKey: orgDashboardsQueryKeys.connectionApps(organizationId, connection.id),View on GitHub (pinned to 2b7df46e8a)
Solutions
- On 404, invalidate orgDashboardsQueryKeys.access and refetch — the grant is already gone; treat as success.
- On 401/403, re-authenticate or verify access-management permissions.
- On 5xx, retry after refetching; confirm whether revocation succeeded before assuming failure.
- Ensure grantId is a current, valid ID from the latest access list response.
Example fix
// before
if (response.status !== 204 && !response.ok) {
throw getRequestError(payload, response, `Failed to revoke dashboard access (${response.status}).`);
}
// after
if (response.status === 404) return input.dashboardId; // grant already revoked
if (response.status !== 204 && !response.ok) {
throw getRequestError(payload, response, `Failed to revoke dashboard access (${response.status}).`);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!input.grantId || typeof input.grantId !== "string") {
throw new Error("A valid grantId is required to revoke access.");
} Type guard
function isGrantId(value: unknown): value is string {
return typeof value === "string" && value.length > 0;
} Try / catch
try {
await revokeAccess.mutateAsync({ dashboardId, grantId });
} catch (error) {
if (isReauthRequiredError(error)) return startReauth();
if (error.message.includes("(404)")) return; // already revoked; refetch
toast.error(error.message);
} finally {
await queryClient.invalidateQueries({ queryKey: orgDashboardsQueryKeys.access(organizationId, dashboardId) });
} Prevention
- Treat 404 on revoke as success — the grant was already removed.
- Always invalidate the access list after revoke attempts.
- Avoid holding stale grantIds from a long-open access panel; refetch on focus.
- Gate the revoke action on the user's access-management permission.
When it happens
Trigger: Revoking a grant that was already removed (404 — e.g. two admins revoking simultaneously), missing permission to manage access (403), expired session (401), malformed grantId, or server error during revocation.
Common situations: The access list is stale and the grant was already revoked elsewhere; the UI kept an old grantId after a refetch raced with the mutation.
Related errors
- Failed to grant dashboard access (${response.status}).
- Failed to create the dashboard (${response.status}).
- Failed to update the dashboard (${response.status}).
- Failed to delete the dashboard (${response.status}).
- Failed to grant plugin access (${response.status}).
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/1f596ee0c5d07793.
Report an issue: GitHub.