danny-avila/LibreChat · error · Error

Failed to authenticate OAuth tool

Error message

Failed to authenticate OAuth tool

What it means

Thrown during an Action's OAuth token exchange/refresh when the underlying token call rejects. The original error is logged; a generic message is re-thrown so callers see a stable failure type rather than leaking provider-specific detail.

Source

Thrown at api/server/services/ActionService.js:302

                data.delta.auth = undefined;
                data.delta.expires_at = undefined;
                const successEventData = { event: GraphEvents.ON_RUN_STEP_DELTA, data };
                if (streamId) {
                  await GenerationJobManager.emitChunk(streamId, successEventData, {
                    expectedCreatedAt: jobCreatedAt,
                  });
                } else {
                  sendEvent(res, successEventData);
                }
                await sleep(3000);
                metadata.oauth_access_token = result.access_token;
                metadata.oauth_refresh_token = result.refresh_token;
                const expiresAt = new Date(Date.now() + result.expires_in * 1000);
                metadata.oauth_token_expires_at = expiresAt.toISOString();
              } catch (error) {
                const errorMessage = 'Failed to authenticate OAuth tool';
                logger.error(errorMessage, error);
                throw new Error(errorMessage);
              }
            };

            const tokenPromises = [];
            tokenPromises.push(findToken({ userId, type: 'oauth', identifier }));
            tokenPromises.push(
              findToken({
                userId,
                type: 'oauth_refresh',
                identifier: `${identifier}:refresh`,
              }),
            );
            const [tokenData, refreshTokenData] = await Promise.all(tokenPromises);

            if (tokenData) {
              // Valid token exists, add it to metadata for setAuth
              metadata.oauth_access_token = await decryptV2(tokenData.token);
              if (refreshTokenData) {

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Re-run the OAuth authorization flow to obtain a fresh access+refresh token pair.
  2. Verify the action's client_id/client_secret and redirect_uri match the provider's app config.
  3. Check provider response in the logs (the original error is logged before this message) for the exact OAuth error.
  4. Ensure server clock is synchronized (NTP) so token expiry is computed correctly.
Defensive patterns

Strategy: retry

Try / catch

try { await validateAndUpdateTool(...); }
catch (e) {
  if (/Failed to authenticate OAuth tool/.test(e.message)) {
    await requestReauthorization();
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: The OAuth token endpoint returns an error, the authorization code is invalid/expired, the refresh token is revoked, or the redirect_uri/client credentials do not match the registered app. Surfaces during validateAndUpdateTool when refreshing or minting a token for an authenticated action.

Common situations: Expired refresh token after a long idle period; rotated OAuth client secret not updated; clock skew rejecting token expiry; provider-side rate limiting or outage during token exchange.

Understand the failure class

Related errors


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/39f9253603c2eff3. Report an issue: GitHub.