different-ai/openwork · error

Failed to archive plugin (${response.status}).

Error message

Failed to archive plugin (${response.status}).

What it means

Thrown by useArchivePlugin in plugin-data.tsx when the POST to /v1/plugins/:id/archive returns a non-ok HTTP status. getRequestError attaches the server payload and status to the thrown error so the UI toast surfaces the real cause. It means the Den API rejected the archive request, not a client-side bug.

Source

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

      queryClient.invalidateQueries({ queryKey: pluginQueryKeys.list() });
    },
  });
}

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

  return useMutation({
    mutationFn: async (pluginId: string) => {
      await runReauthableAction("archive-plugin", async () => {
        const { response, payload } = await requestJson(
          `/v1/plugins/${encodeURIComponent(pluginId)}/archive`,
          { method: "POST" },
          15000,
        );
        if (!response.ok) {
          throw getRequestError(payload, response, `Failed to archive plugin (${response.status}).`);
        }
      });
      return pluginId;
    },
    onSuccess: (pluginId) => {
      queryClient.removeQueries({ queryKey: pluginQueryKeys.detail(pluginId) });
      queryClient.invalidateQueries({ queryKey: pluginQueryKeys.list() });
    },
  });
}

export function useAttachWorkflowToPlugin(pluginId: string) {
  const queryClient = useQueryClient();
  const { runReauthableAction } = useOrgDashboard();

  return useMutation({
    mutationFn: async (workflowId: string) => {
      await runReauthableAction("attach-workflow-to-plugin", async () => {

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Check the HTTP status embedded in the error message and the server payload for the real reason (401 -> re-authenticate, 403 -> confirm org role, 404 -> refresh plugin list).
  2. Refresh the dashboard so the plugin list is not stale before retrying the archive.
  3. If 5xx or timeout, retry after confirming the Den server is healthy (server logs, uptime).
  4. Verify the logged-in account still has plugin management permissions on the org.

Example fix

// before: retrying archive on a stale id
await archivePlugin(pluginId);
// after: confirm the plugin still exists server-side first
const detail = await fetchPluginDetail(pluginId);
if (detail) await archivePlugin(pluginId);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!pluginId || typeof pluginId !== 'string') throw new Error('pluginId is required before archiving.');

Type guard

function isPluginId(v: unknown): v is string {
  return typeof v === 'string' && v.length > 0;
}

Try / catch

try {
  await archivePlugin(pluginId);
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e);
  if (msg.includes('401')) promptReSignIn();
  else if (msg.includes('403')) toast('You need org admin permission to archive plugins.');
  else if (msg.includes('404')) { await refreshPluginList(); toast('Plugin no longer exists.'); }
  else toast(msg);
}

Prevention

When it happens

Trigger: POST /v1/plugins/{pluginId}/archive responds 4xx/5xx: plugin id not found (404), caller lacks org-admin permission (403), session expired (401), or server error (5xx). 15s timeout exceeded also surfaces as failure.

Common situations: Archiving a plugin that was already deleted by a teammate; stale dashboard data after role downgrade; Den server restart/maintenance window; expired Better-Auth session token.

Related errors


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