{"record":{"id":"98676b8bf5df7e2a","repo":"twentyhq/twenty","slug":"app-connection-connectionid-requires-the-user-t","errorCode":null,"errorMessage":"App connection ${connectionId} requires the user to reconnect (authFailedAt is set). Surface a \"Reconnect\" prompt in your UI.","messagePattern":"App connection (.+?) requires the user to reconnect \\(authFailedAt is set\\)\\. Surface a \"Reconnect\" prompt in your UI\\.","errorType":"exception","errorClass":"AppConnectionAuthFailedError","httpStatus":null,"severity":"error","filePath":"packages/twenty-sdk/src/sdk/logic-function/connections/get-connection.ts","lineNumber":32,"sourceCode":"      accessToken\n      scopes\n      authFailedAt\n    }\n  }\n`;\n\nexport const getConnection = async (id: string): Promise<AppConnection> => {\n  const { appConnection } = await postGraphqlRequest<\n    { id: string },\n    { appConnection: AppConnection }\n  >({\n    query: GET_APP_CONNECTION_QUERY,\n    variables: { id },\n    caller: 'getConnection',\n  });\n\n  if (appConnection.authFailedAt !== null) {\n    throw new AppConnectionAuthFailedError(appConnection.id);\n  }\n\n  return appConnection;\n};\n","sourceCodeStart":14,"sourceCodeEnd":37,"githubUrl":"https://github.com/twentyhq/twenty/blob/1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6/packages/twenty-sdk/src/sdk/logic-function/connections/get-connection.ts#L14-L37","documentation":"Thrown by getConnection when the fetched AppConnection has a non-null authFailedAt timestamp. This means the connection's OAuth refresh failed permanently — the access token can no longer be renewed and the end user must manually reconnect from the app's settings. The SDK cannot recover this programmatically. The error class (AppConnectionAuthFailedError) exposes connectionId so callers can build a reconnect UI targeting the right connection.","triggerScenarios":"Calling getConnection(id) where the server returns an AppConnection with authFailedAt !== null. This happens when the OAuth provider revoked the token, the refresh token expired, the user revoked access from the provider's settings, or the connection's scopes changed and re-authorization is required.","commonSituations":"A user's Google/Microsoft OAuth token expired after 6 months and the refresh failed. The user revoked the app from their Google account settings. The OAuth provider changed their API requiring re-authorization. The connection was working but the provider's token endpoint started returning permanent errors.","solutions":["Catch AppConnectionAuthFailedError and surface a 'Reconnect' prompt to the end user with the connectionId.","Redirect the user to the Twenty settings page where they can re-authorize the connection.","Use listConnections (which filters out auth-failed connections by default) to find healthy alternatives.","After the user reconnects, the same connectionId can be retried via getConnection."],"exampleFix":"// before\nconst conn = await getConnection(connectionId);\n\n// after — handle auth failure gracefully\nimport { AppConnectionAuthFailedError } from 'twenty-sdk';\ntry {\n  const conn = await getConnection(connectionId);\n} catch (e) {\n  if (e instanceof AppConnectionAuthFailedError) {\n    showReconnectPrompt(e.connectionId);\n    return;\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"import { AppConnectionAuthFailedError } from 'twenty-sdk';\n\nconst isAuthFailedError = (\n  error: unknown,\n): error is AppConnectionAuthFailedError => {\n  return error instanceof AppConnectionAuthFailedError;\n};","tryCatchPattern":"import { getConnection, AppConnectionAuthFailedError } from 'twenty-sdk';\n\ntry {\n  const conn = await getConnection(connectionId);\n} catch (error) {\n  if (error instanceof AppConnectionAuthFailedError) {\n    // Surface reconnect UI with error.connectionId\n    showReconnectDialog(error.connectionId);\n    return;\n  }\n  throw error;\n}","preventionTips":["Always catch AppConnectionAuthFailedError separately from generic errors.","Use listConnections to find healthy connections and avoid operating on failed ones.","Build a reconnect flow that deep-links the user to the Twenty connection settings page.","After reconnect, retry getConnection with the same id — it will succeed once authFailedAt clears."],"tags":["sdk","connections","oauth","authentication","user-action-required"],"backgroundTag":null,"analyzedSha":"1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6","analyzedAt":"2026-08-12T15:37:27.593Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}