{"record":{"id":"39f9253603c2eff3","repo":"danny-avila/LibreChat","slug":"failed-to-authenticate-oauth-tool","errorCode":null,"errorMessage":"Failed to authenticate OAuth tool","messagePattern":"Failed to authenticate OAuth tool","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"api/server/services/ActionService.js","lineNumber":302,"sourceCode":"                data.delta.auth = undefined;\n                data.delta.expires_at = undefined;\n                const successEventData = { event: GraphEvents.ON_RUN_STEP_DELTA, data };\n                if (streamId) {\n                  await GenerationJobManager.emitChunk(streamId, successEventData, {\n                    expectedCreatedAt: jobCreatedAt,\n                  });\n                } else {\n                  sendEvent(res, successEventData);\n                }\n                await sleep(3000);\n                metadata.oauth_access_token = result.access_token;\n                metadata.oauth_refresh_token = result.refresh_token;\n                const expiresAt = new Date(Date.now() + result.expires_in * 1000);\n                metadata.oauth_token_expires_at = expiresAt.toISOString();\n              } catch (error) {\n                const errorMessage = 'Failed to authenticate OAuth tool';\n                logger.error(errorMessage, error);\n                throw new Error(errorMessage);\n              }\n            };\n\n            const tokenPromises = [];\n            tokenPromises.push(findToken({ userId, type: 'oauth', identifier }));\n            tokenPromises.push(\n              findToken({\n                userId,\n                type: 'oauth_refresh',\n                identifier: `${identifier}:refresh`,\n              }),\n            );\n            const [tokenData, refreshTokenData] = await Promise.all(tokenPromises);\n\n            if (tokenData) {\n              // Valid token exists, add it to metadata for setAuth\n              metadata.oauth_access_token = await decryptV2(tokenData.token);\n              if (refreshTokenData) {","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/danny-avila/LibreChat/blob/5ff282f9006c436e561de1afd39a481bea1ef0d8/api/server/services/ActionService.js#L284-L320","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-run the OAuth authorization flow to obtain a fresh access+refresh token pair.","Verify the action's client_id/client_secret and redirect_uri match the provider's app config.","Check provider response in the logs (the original error is logged before this message) for the exact OAuth error.","Ensure server clock is synchronized (NTP) so token expiry is computed correctly."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await validateAndUpdateTool(...); }\ncatch (e) {\n  if (/Failed to authenticate OAuth tool/.test(e.message)) {\n    await requestReauthorization();\n    return;\n  }\n  throw e;\n}","preventionTips":["Refresh tokens proactively before expiry (use oauth_token_expires_at).","Log the wrapped provider error so the root cause is diagnosable.","Keep client secrets current; rotate on a schedule."],"tags":["oauth","actions","authentication","token-refresh"],"backgroundTag":null,"analyzedSha":"5ff282f9006c436e561de1afd39a481bea1ef0d8","analyzedAt":"2026-08-12T21:38:08.145Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}