FlowiseAI/Flowise · error · Error
Access token is expired and no refresh token is available. P
Error message
Access token is expired and no refresh token is available. Please re-authorize the credential.
What it means
Thrown by refreshOAuth2Token when credentialData.expires_at indicates the token is past the buffer window (5 min default) AND credentialData.refresh_token is absent. There is no way to silently refresh, so the only recovery is interactive re-authorization of the OAuth2 credential.
Source
Thrown at packages/components/src/utils.ts:1467
* @param {ICommonObject} credentialData
* @param {ICommonObject} options
* @param {number} bufferTimeMs - Buffer time in milliseconds before expiry (default: 5 minutes)
* @returns {Promise<ICommonObject>}
*/
export const refreshOAuth2Token = async (
credentialId: string,
credentialData: ICommonObject,
options: ICommonObject,
bufferTimeMs: number = 5 * 60 * 1000
): Promise<ICommonObject> => {
// Check if token is expired and refresh if needed
if (credentialData.expires_at) {
const expiryTime = new Date(credentialData.expires_at)
const currentTime = new Date()
if (currentTime.getTime() > expiryTime.getTime() - bufferTimeMs) {
if (!credentialData.refresh_token) {
throw new Error('Access token is expired and no refresh token is available. Please re-authorize the credential.')
}
try {
// Import fetch dynamically to avoid issues
const fetch = (await import('node-fetch')).default
// Call the refresh API endpoint
const refreshResponse = await fetch(
`${options.baseURL || 'http://localhost:3000'}/api/v1/oauth2-credential/refresh/${credentialId}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
}
)
if (!refreshResponse.ok) {View on GitHub (pinned to abe4a8601a)
Solutions
- Re-authorize the OAuth2 credential through Flowise to obtain a fresh access + refresh token pair.
- When authorizing, request the offline_access / appropriate scope so the provider issues a refresh_token.
- Ensure the credential persistence layer stores the refresh_token returned by each refresh (rotate single-use refresh tokens).
- Increase bufferTimeMs if the issue is clock skew between Flowise and the provider.
Example fix
// before
if (!credentialData.refresh_token) {
throw new Error('Access token is expired and no refresh token is available. Please re-authorize the credential.')
}
// after — actionable message with the provider context
if (!credentialData.refresh_token) {
throw new Error(
`Access token for credential ${credentialId} expired at ${credentialData.expires_at} and no refresh_token is stored. ` +
`Re-authorize the credential and ensure the OAuth scope includes offline_access/refresh_tokens.`
)
} Defensive patterns
Strategy: validation
Validate before calling
function canRefreshOAuth2(cred: ICommonObject): boolean {
return Boolean(cred && typeof cred.refresh_token === 'string' && cred.refresh_token.length > 0)
} Type guard
function hasRefreshToken(cred: unknown): cred is { refresh_token: string; expires_at?: string } {
return typeof cred === 'object' && cred !== null && typeof (cred as any).refresh_token === 'string'
} Try / catch
if (currentTime.getTime() > expiryTime.getTime() - bufferTimeMs) {
if (!hasRefreshToken(credentialData)) {
throw new Error(`Access token expired at ${credentialData.expires_at}; no refresh_token stored. Re-authorize credential ${credentialId}.`)
}
// proceed with refresh
} Prevention
- Request offline_access / refresh scope at authorization time.
- Persist the rotated refresh_token after each refresh for single-use-token providers.
- Surface a UI warning before tokens expire so users re-authorize proactively.
When it happens
Trigger: The OAuth2 provider did not return a refresh_token at authorization time (some scopes/server flows omit it); the refresh_token was dropped during credential storage/serialization; the credential was authorized with a grant type that doesn't issue refresh tokens (e.g. implicit); a previous refresh consumed a single-use refresh token that wasn't persisted back.
Common situations: Google/Microsoft OAuth where offline_access scope wasn't requested; the provider's refresh token is single-use and the new one wasn't saved after the last refresh; credentials imported/exported without the refresh_token field; token expiry after a long Flowise downtime.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Failed to refresh token: ${refreshResponse.status} ${refresh
- Failed to refresh access token: ${error instanceof Error ? e
- Firecrawl API key not set. You can set it as FIRECRAWL_API_K
- API Key Required
- Invalid credentials: provide either Bearer Token or Username
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/6db49d126c0f3db7.
Report an issue: GitHub.