different-ai/openwork · error

Failed to load plugin access (${response.status}).

Error message

Failed to load plugin access (${response.status}).

What it means

usePluginAccess fetches GET /v1/plugins/:id/access from the Den API. When the HTTP response status is not 2xx it throws this error, preferring a server-provided message extracted from the error payload via getErrorMessage, with the status-embedded fallback string if the payload has no usable message. It surfaces through TanStack Query as the query's error.

Source

Thrown at ee/apps/den-web/app/(den)/dashboard/_components/plugin-access-data.tsx:90

    role,
    createdByOrgMembershipId,
    createdAt,
    removedAt,
  };
}

export function usePluginAccess(pluginId: string) {
  return useQuery({
    enabled: Boolean(pluginId),
    queryKey: pluginAccessQueryKeys.detail(pluginId),
    queryFn: async (): Promise<PluginAccessGrant[]> => {
      const { response, payload } = await requestJson(
        `/v1/plugins/${encodeURIComponent(pluginId)}/access`,
        { method: "GET" },
        15000,
      );
      if (!response.ok) {
        throw new Error(getErrorMessage(payload, `Failed to load plugin access (${response.status}).`));
      }
      const items = isRecord(payload) && Array.isArray(payload.items) ? payload.items : [];
      return items
        .map(parsePluginAccessGrant)
        .filter((grant): grant is PluginAccessGrant => grant !== null && grant.removedAt === null);
    },
  });
}

type GrantPluginAccessBody =
  | { orgMembershipId: string; teamId?: never; orgWide?: never; role: PluginAccessRole }
  | { orgMembershipId?: never; teamId: string; orgWide?: never; role: PluginAccessRole }
  | { orgMembershipId?: never; teamId?: never; orgWide: true; role: PluginAccessRole };

export function useGrantPluginAccess() {
  const queryClient = useQueryClient();
  const { runReauthableAction } = useOrgDashboard();

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Sign in again / refresh the session to clear 401/403, then reload the dashboard page.
  2. Verify the pluginId is valid for the current org by loading /v1/plugins/{id} directly (curl or browser devtools network tab).
  3. Confirm the Den server version supports the plugin access endpoint; upgrade the self-hosted server if 404/405 persists.
  4. Check Den server logs for 5xx causes (DB connectivity, migration lag) if the status is 500/502/503.

Example fix

// before: raw queryFn throwing with opaque fallback
throw new Error(getErrorMessage(payload, `Failed to load plugin access (${response.status}).`));
// after: handle 401 by re-authenticating instead of throwing
if (response.status === 401) {
  await redirectToSignIn();
  return [];
}
if (!response.ok) {
  throw new Error(getErrorMessage(payload, `Failed to load plugin access (${response.status}).`));
}
Defensive patterns

Strategy: try-catch

Validate before calling

const pluginIdOk = typeof pluginId === "string" && pluginId.length > 0;
const sessionOk = document.cookie.includes("den-session") || Boolean(await getSession());
if (!pluginIdOk || !sessionOk) { await redirectToSignIn(); }

Type guard

function hasUsableErrorPayload(p: unknown): p is { message: string } {
  return typeof p === "object" && p !== null && typeof (p as { message?: unknown }).message === "string";
}

Try / catch

try {
  const access = await pluginAccessQuery(pluginId);
} catch (err) {
  const status = /\((\d{3})\)\.$/.exec(err instanceof Error ? err.message : "")?.[1];
  if (status === "401") { await redirectToSignIn(); }
  else if (status === "404") { showNotFound(pluginId); }
  else { showToast(`Could not load plugin access${status ? ` (${status})` : ""}; retry later.`); }
}

Prevention

When it happens

Trigger: The GET /v1/plugins/{pluginId}/access request returns 401/403 (missing or expired session, no org membership), 404 (pluginId does not exist or is not visible to the caller), 5xx (Den server/DB failure), or a network-level failure yields an error status from requestJson.

Common situations: An expired Den session cookie after idle timeout; a plugin removed by an org admin while a dashboard tab is still open; pointing den-web at a server that lacks the plugin access endpoint (version mismatch); an org slug/plugin id pasted from another org.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/3d1084aa5fb89419. Report an issue: GitHub.