{"record":{"id":"e4da1228c24d4862","repo":"different-ai/openwork","slug":"failed-to-disconnect-integration-response-statu","errorCode":null,"errorMessage":"Failed to disconnect integration (${response.status}).","messagePattern":"Failed to disconnect integration \\((.+?)\\)\\.","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ee/apps/den-web/app/(den)/dashboard/_components/integration-data.tsx","lineNumber":900,"sourceCode":"  const queryClient = useQueryClient();\n  const { runReauthableAction } = useOrgDashboard();\n\n  return useMutation({\n    mutationFn: async (connectionId: string) => {\n      let result: string | null = null;\n      await runReauthableAction(\"disconnect-integration\", async () => {\n      const isGithubConnection = connectionId.startsWith(\"cac_\");\n      if (isGithubConnection) {\n        const { response, payload } = await requestJson(\n          `/v1/connector-accounts/${encodeURIComponent(connectionId)}/disconnect`,\n          {\n            method: \"POST\",\n            body: JSON.stringify({ reason: \"Disconnected from Den Web integrations.\" }),\n          },\n          20000,\n        );\n        if (!response.ok) {\n          throw getRequestError(payload, response, `Failed to disconnect integration (${response.status}).`);\n        }\n        result = connectionId;\n        return;\n      }\n\n      await simulateLatency(300);\n      mockConnections = mockConnections.filter((entry) => entry.id !== connectionId);\n        result = connectionId;\n      });\n      if (!result) {\n        throw new Error(\"Disconnect response was incomplete.\");\n      }\n      return result;\n    },\n    onSuccess: () => {\n      queryClient.invalidateQueries({ queryKey: integrationQueryKeys.all });\n      queryClient.invalidateQueries({ queryKey: [\"plugins\"] });\n    },","sourceCodeStart":882,"sourceCodeEnd":918,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/dashboard/_components/integration-data.tsx#L882-L918","documentation":"Thrown when disconnecting an integration fails. For connections with a connectionId the code POSTs {reason:'Disconnected from Den Web integrations.'} to the disconnect endpoint (20s timeout) and throws getRequestError on non-ok; otherwise it falls back to a simulated-latency local disconnect path. getRequestError (den-flow.ts:527) may instead return a ReauthRequiredError for 403 {error:'reauth'}.","triggerScenarios":"The disconnect POST returns non-ok: 401/403 (session expired, no permission on the integration, or reauth required), 404 (connection already removed server-side), 409/422 (connection is in use by active runs or policies), 5xx (provider or Den server failure).","commonSituations":"Trying to disconnect an integration another admin already removed; org policy blocks disconnecting a connector that desktop policies depend on; stale tab with an expired session; provider outage during disconnect cleanup.","solutions":["On 404, treat the integration as already disconnected: refresh the integration list and clear local state.","On 401/403, run the reauth/sign-in flow (check isReauthRequiredError) then retry.","If the server says the connection is in use, remove dependent policies/automations first, then disconnect.","On 5xx/timeout, retry the disconnect; it is idempotent per connectionId."],"exampleFix":"// before\nif (!response.ok) {\n  throw getRequestError(payload, response, `Failed to disconnect integration (${response.status}).`);\n}\n// after\nif (!response.ok) {\n  if (response.status === 404) {\n    return connectionId; // already gone server-side\n  }\n  throw getRequestError(payload, response, `Failed to disconnect integration (${response.status}).`);\n}","handlingStrategy":"try-catch","validationCode":"// before disconnecting\nif (!connectionId) throw new Error(\"No server-side connection to disconnect.\");\n// optionally confirm no dependents:\nconst dependents = getDependentPolicies(integrationId);\nif (dependents.length > 0) throw new Error(\"Remove linked policies first.\");","typeGuard":"function isReauthError(e: unknown): e is ReauthRequiredError {\n  return e instanceof ReauthRequiredError;\n}","tryCatchPattern":"try {\n  await disconnectMutation.mutateAsync({ connectionId });\n} catch (error) {\n  if (isReauthError(error)) { startReauth(); return; }\n  if (/\\(404\\)/.test(error.message)) { clearLocalIntegration(integrationId); return; }\n  showToast(error.message);\n}","preventionTips":["Refresh the integration list before disconnecting to avoid 404 on already-removed connections.","Make the disconnect button idempotent: 404 means success.","Check for dependent policies/automations client-side before calling the API.","Require confirmation dialog so a stray click does not fire the POST."],"tags":["http","integrations","den-api","react-query"],"backgroundTag":"http-non-ok-response","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}