different-ai/openwork · error · Error

Failed to remove connector instance (${response.status}).

Error message

Failed to remove connector instance (${response.status}).

What it means

Thrown when removing a connector instance fails. The mutation POSTs to /v1/connector-instances/{id}/remove (20s timeout) and throws getRequestError(payload, response, ...) when response.ok is false. The returned error carries the server's `error` message or the fallback "Failed to remove connector instance (<status>)."; 403 {error:'reauth'} becomes ReauthRequiredError via getRequestError in den-flow.ts:527.

Source

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

    },
  });
}

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

  return useMutation({
    mutationFn: async (connectorInstanceId: string) => {
      await runReauthableAction("remove-connector-instance", async () => {
      const { response, payload } = await requestJson(
        `/v1/connector-instances/${encodeURIComponent(connectorInstanceId)}/remove`,
        { method: "POST" },
        20000,
      );

      if (!response.ok) {
        throw getRequestError(payload, response, `Failed to remove connector instance (${response.status}).`);
      }

      });
      return connectorInstanceId;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: integrationQueryKeys.all });
      queryClient.invalidateQueries({ queryKey: ["plugins"] });
    },
  });
}

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. On 404, treat removal as successful: invalidate queries and drop the row locally.
  2. If the server reports dependent resources, delete the linked plugins/policies first, then retry removal.
  3. For 403 reauth errors, check isReauthRequiredError and start the sign-in flow.
  4. On 5xx, retry once; verify in GitHub that the App installation/webhooks were cleaned up.

Example fix

// before
if (!response.ok) {
  throw getRequestError(payload, response, `Failed to remove connector instance (${response.status}).`);
}
// after
if (!response.ok) {
  if (response.status === 404) return connectorInstanceId; // already removed
  throw getRequestError(payload, response, `Failed to remove connector instance (${response.status}).`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before remove
if (!connectorInstanceId) throw new Error("connectorInstanceId is required.");
const deps = getLinkedPlugins(connectorInstanceId);
if (deps.length > 0) throw new Error(`Remove ${deps.length} linked plugins first.`);

Type guard

function isReauthError(e: unknown): e is ReauthRequiredError {
  return e instanceof ReauthRequiredError;
}

Try / catch

try {
  await removeMutation.mutateAsync({ connectorInstanceId });
} catch (error) {
  if (isReauthError(error)) { startReauth(); return; }
  if (/\(404\)/.test(error.message)) { queryClient.invalidateQueries(connectorKeys.list); return; }
  showToast(error.message);
}

Prevention

When it happens

Trigger: POST remove returns non-ok: 401/403 (no permission or session expired), 404 (instance already removed), 409/422 (instance owns resources — plugins, policies, running imports — that block removal), 5xx (server-side cleanup of GitHub webhooks/installation failed).

Common situations: Double-clicking Remove so the second call 404s; org policy references the connector's plugins so removal is rejected; GitHub-side uninstall happened first causing server cleanup errors; expired session in a long-open dashboard tab.

Related errors


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