twentyhq/twenty · error · AppConnectionAuthFailedError

App connection ${connectionId} requires the user to reconnec

Error message

App connection ${connectionId} requires the user to reconnect (authFailedAt is set). Surface a "Reconnect" prompt in your UI.

What it means

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.

Source

Thrown at packages/twenty-sdk/src/sdk/logic-function/connections/get-connection.ts:32

      accessToken
      scopes
      authFailedAt
    }
  }
`;

export const getConnection = async (id: string): Promise<AppConnection> => {
  const { appConnection } = await postGraphqlRequest<
    { id: string },
    { appConnection: AppConnection }
  >({
    query: GET_APP_CONNECTION_QUERY,
    variables: { id },
    caller: 'getConnection',
  });

  if (appConnection.authFailedAt !== null) {
    throw new AppConnectionAuthFailedError(appConnection.id);
  }

  return appConnection;
};

View on GitHub (pinned to 1f5dd2bbd2)

Solutions

  1. Catch AppConnectionAuthFailedError and surface a 'Reconnect' prompt to the end user with the connectionId.
  2. Redirect the user to the Twenty settings page where they can re-authorize the connection.
  3. Use listConnections (which filters out auth-failed connections by default) to find healthy alternatives.
  4. After the user reconnects, the same connectionId can be retried via getConnection.

Example fix

// before
const conn = await getConnection(connectionId);

// after — handle auth failure gracefully
import { AppConnectionAuthFailedError } from 'twenty-sdk';
try {
  const conn = await getConnection(connectionId);
} catch (e) {
  if (e instanceof AppConnectionAuthFailedError) {
    showReconnectPrompt(e.connectionId);
    return;
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Type guard

import { AppConnectionAuthFailedError } from 'twenty-sdk';

const isAuthFailedError = (
  error: unknown,
): error is AppConnectionAuthFailedError => {
  return error instanceof AppConnectionAuthFailedError;
};

Try / catch

import { getConnection, AppConnectionAuthFailedError } from 'twenty-sdk';

try {
  const conn = await getConnection(connectionId);
} catch (error) {
  if (error instanceof AppConnectionAuthFailedError) {
    // Surface reconnect UI with error.connectionId
    showReconnectDialog(error.connectionId);
    return;
  }
  throw error;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12). Data as JSON: /api/errors/98676b8bf5df7e2a. Report an issue: GitHub.