{"record":{"id":"5058376fe443e213","repo":"danny-avila/LibreChat","slug":"authentication-failed-error-message","errorCode":null,"errorMessage":"Authentication failed: ${error.message}","messagePattern":"Authentication failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"api/server/services/ActionService.js","lineNumber":380,"sourceCode":"                metadata.oauth_token_expires_at = expiresAt.toISOString();\n              } catch (error) {\n                logger.error('Failed to refresh token, requesting new login:', error);\n                await requestLogin();\n              }\n            } else {\n              await requestLogin();\n            }\n          }\n\n          await preparedExecutor.setAuth(metadata);\n        } catch (error) {\n          if (\n            error.message.includes('No access token found') ||\n            error.message.includes('Access token is expired')\n          ) {\n            throw error;\n          }\n          throw new Error(`Authentication failed: ${error.message}`);\n        }\n      }\n\n      const response = await preparedExecutor.execute(ssrfAgents);\n\n      if (typeof response.data === 'object') {\n        return JSON.stringify(response.data);\n      }\n      return response.data;\n    } catch (error) {\n      const message = `API call to ${action.metadata.domain} failed:`;\n      return logAxiosError({ message, error });\n    }\n  };\n\n  if (name) {\n    return tool(_call, {\n      name: name.replace(replaceSeparatorRegex, '_'),","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/danny-avila/LibreChat/blob/5ff282f9006c436e561de1afd39a481bea1ef0d8/api/server/services/ActionService.js#L362-L398","documentation":"Thrown by the Action executor when setAuth fails for any reason other than a missing or expired access token (those are re-thrown unchanged so the caller can trigger a re-login). All other auth-setup failures are normalized to 'Authentication failed: <reason>'.","triggerScenarios":"preparedExecutor.setAuth rejects with an error whose message is neither 'No access token found' nor 'Access token is expired' — e.g. malformed metadata, a signing/encryption error, or an unexpected auth scheme mismatch.","commonSituations":"Corrupted action metadata after a partial migration; an action whose auth type changed but whose stored metadata is stale; encryption key rotation breaking stored secret decryption.","solutions":["Inspect the wrapped error.message (it is included) to find the underlying cause.","Re-configure the action's authentication (re-enter credentials / re-run OAuth).","If encryption keys were rotated, re-encrypt or re-enter stored secrets.","Delete and recreate the action if its metadata is irrecoverably stale."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isMissingOrExpiredTokenError(e) {\n  const m = e?.message ?? '';\n  return m.includes('No access token found') || m.includes('Access token is expired');\n}","tryCatchPattern":"try { await preparedExecutor.setAuth(metadata); }\ncatch (e) {\n  if (isMissingOrExpiredTokenError(e)) { await requestLogin(); throw e; }\n  throw new Error(`Authentication failed: ${e.message}`);\n}","preventionTips":["Normalize auth errors at the boundary so only known types propagate.","Validate action metadata shape before setAuth.","Re-encrypt stored secrets after key rotations."],"tags":["actions","authentication","metadata","error-wrapping"],"backgroundTag":null,"analyzedSha":"5ff282f9006c436e561de1afd39a481bea1ef0d8","analyzedAt":"2026-08-12T21:38:08.145Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}