{"record":{"id":"f06ae4119d5d13a6","repo":"different-ai/openwork","slug":"action-connectionname-is-no-longer-available-as","errorCode":null,"errorMessage":"${action.connectionName} is no longer available as your reconnectable account.","messagePattern":"(.+?) is no longer available as your reconnectable account\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/app/src/react-app/domains/session/surface/session-surface.tsx","lineNumber":2374,"sourceCode":"    const scope: ChatMcpReconnectScope = {\n      baseUrl: settings.baseUrl,\n      token,\n      organizationId,\n    };\n    const currentScope = (): ChatMcpReconnectScope => {\n      const current = readDenSettings();\n      return {\n        baseUrl: current.baseUrl,\n        token: current.authToken?.trim() ?? \"\",\n        organizationId: current.activeOrgId?.trim() ?? \"\",\n      };\n    };\n    try {\n      const denClient = createDenClient({ baseUrl: settings.baseUrl, token });\n      const connections = await denClient.listMcpConnections(organizationId, \"usable\");\n      const connection = connections.find((entry) => entry.id === action.connectionId);\n      if (!connection || connection.authType !== \"oauth\" || connection.credentialMode !== \"per_member\") {\n        throw new Error(`${action.connectionName} is no longer available as your reconnectable account.`);\n      }\n\n      recordInspectorEvent(\"mcp.chat_reconnect.started\", {\n        workspaceId: props.workspaceId,\n        sessionId: props.sessionId,\n        connectionId: action.connectionId,\n      });\n      onProgress({ phase: \"opening\" });\n      const result = await denClient.startMcpConnectionConnect(organizationId, action.connectionId);\n      if (result.status === \"connected\") {\n        recordInspectorEvent(\"mcp.chat_reconnect.completed\", {\n          workspaceId: props.workspaceId,\n          sessionId: props.sessionId,\n          connectionId: action.connectionId,\n          completion: \"already_connected\",\n        });\n        return \"connected\";\n      }","sourceCodeStart":2356,"sourceCodeEnd":2392,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/app/src/react-app/domains/session/surface/session-surface.tsx#L2356-L2392","documentation":"After fetching the org's usable MCP connections from Den, the code validates the requested connection still exists and is an OAuth connection with per-member credential mode. If the id is missing from the list or the authType/credentialMode don't match, the stored reconnect action is stale, so it throws with the connection's display name.","triggerScenarios":"Reconnect action references action.connectionId that no longer appears in denClient.listMcpConnections(organizationId, \"usable\"), or the connection's authType is not \"oauth\" or credentialMode is not \"per_member\".","commonSituations":"Admin removed or disabled the connection in Den; connection changed from per-member OAuth to shared credentials; stale UI state after org switch; connection renamed/rotated server-side between when the action was surfaced and clicked.","solutions":["Refresh the connection list in the UI and re-surface only currently reconnectable (oauth + per_member) connections","Check the connection's status/config in the OpenWork Cloud admin console and restore OAuth per-member credentials","Clear stale reconnect actions and have the user initiate a fresh reconnect","If the org changed, ensure the reconnect uses the currently active organization's connections"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const connections = await denClient.listMcpConnections(orgId, \"usable\");\nconst stillValid = connections.some(\n  (c) => c.id === action.connectionId && c.authType === \"oauth\" && c.credentialMode === \"per_member\"\n);\nif (!stillValid) refreshConnectionActions();","typeGuard":"const isReconnectable = (c: McpConnection): c is McpConnection & { authType: \"oauth\"; credentialMode: \"per_member\" } =>\n  c.authType === \"oauth\" && c.credentialMode === \"per_member\";","tryCatchPattern":"try {\n  await reconnect(action);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"no longer available\")) {\n    await refreshConnections();\n    toast.info(`${action.connectionName} must be re-added before reconnecting.`);\n  } else throw e;\n}","preventionTips":["Re-verify connection validity immediately before showing reconnect actions","Listen for org/connection change events and invalidate cached actions","Only surface connections with authType oauth and credentialMode per_member as reconnectable","Refetch the connection list on org switch or settings focus"],"tags":["oauth","mcp","stale-state"],"backgroundTag":"stale-connection-state","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}