FlowiseAI/Flowise · error · Error
Failed to refresh access token: ${error instanceof Error ? e
Error message
Failed to refresh access token: ${error instanceof Error ? error.message : 'Unknown error'}. Please re-authorize the credential. What it means
Outer catch-all in the OAuth2 refresh try block. Any exception thrown inside the refresh flow (the non-ok throw above, a network error from fetch, a JSON parse error, or getCredentialData failure) is rewrapped with this message and 'Please re-authorize the credential.' It deliberately loses the distinction between network failures and provider rejections.
Source
Thrown at packages/components/src/utils.ts:1498
'Content-Type': 'application/json'
}
}
)
if (!refreshResponse.ok) {
const errorData = await refreshResponse.text()
throw new Error(`Failed to refresh token: ${refreshResponse.status} ${refreshResponse.statusText} - ${errorData}`)
}
await refreshResponse.json()
// Get the updated credential data
const updatedCredentialData = await getCredentialData(credentialId, options)
return updatedCredentialData
} catch (error) {
console.error('Failed to refresh access token:', error)
throw new Error(
`Failed to refresh access token: ${
error instanceof Error ? error.message : 'Unknown error'
}. Please re-authorize the credential.`
)
}
}
}
// Token is not expired, return original data
return credentialData
}
export const stripHTMLFromToolInput = (input: string) => {
const turndownService = new TurndownService()
let cleanedInput = turndownService.turndown(input)
// After conversion, replace any escaped underscores and square brackets with regular unescaped ones
cleanedInput = cleanedInput.replace(/\\([_[\]])/g, '$1')
return cleanedInputView on GitHub (pinned to abe4a8601a)
Solutions
- Distinguish transient failures (network/timeout) from permanent ones (invalid_grant) — only advise re-authorization for permanent failures.
- Confirm options.baseURL resolves and the Flowise API is reachable from the process running refreshOAuth2Token.
- Ensure node-fetch is installed (or switch to global fetch on Node >= 18).
- Inspect the cause/inner message already embedded in the thrown string to pick the right fix.
Example fix
// before
} catch (error) {
console.error('Failed to refresh access token:', error)
throw new Error(`Failed to refresh access token: ${error instanceof Error ? error.message : 'Unknown error'}. Please re-authorize the credential.`)
}
// after — only demand re-auth for permanent failures; retry/propagate transient ones
} catch (error) {
const msg = error instanceof Error ? error.message : String(error)
const isPermanent = /invalid_grant|invalid_client|unauthorized|401|400/.test(msg)
if (isPermanent) {
throw new Error(`Failed to refresh access token: ${msg}. Please re-authorize the credential.`)
}
throw new Error(`Transient failure refreshing access token for ${credentialId}: ${msg}`, { cause: error })
} Defensive patterns
Strategy: retry
Validate before calling
function isTransientRefreshError(msg: string): boolean {
return /ETIMEDOUT|ECONNREFUSED|ENOTFOUND|fetch failed|network|5\d\d/i.test(msg) && !/invalid_grant/.test(msg)
} Type guard
function isNodeFetchTypeError(e: unknown): boolean {
return e instanceof TypeError && /fetch|network|socket/i.test(e.message)
} Try / catch
} catch (error) {
const msg = error instanceof Error ? error.message : String(error)
if (isTransientRefreshError(msg)) {
// retry with backoff, do NOT tell the user to re-authorize
throw new Error(`Transient token refresh failure: ${msg}`, { cause: error })
}
throw new Error(`Failed to refresh access token: ${msg}. Please re-authorize the credential.`)
} Prevention
- Use Node >= 18 global fetch or guarantee node-fetch is installed.
- Retry transient network failures before declaring the credential dead.
- Separate permanent (invalid_grant) from transient (network) failures in error messages.
When it happens
Trigger: node-fetch throws TypeError (DNS failure, connection refused to the refresh endpoint); the inner throw from a non-ok response propagates here; refreshResponse.json() throws because the body isn't JSON; getCredentialData(credentialId, options) throws because the credential was concurrently deleted; the dynamic import('node-fetch') fails because the dependency isn't installed.
Common situations: Flowise API server unreachable at refresh time (wrong baseURL, server down); node-fetch not in dependencies after a refactor; concurrent credential deletion; transient network blips being treated as permanent auth failures.
Related errors
- Access token is expired and no refresh token is available. P
- Failed to refresh token: ${refreshResponse.status} ${refresh
- ${errorMessage}
- Microsoft Graph request failed: ${error instanceof Error ? e
- Failed to make GET request: ${error instanceof Error ? error
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/9e7b1cb46db86f34.
Report an issue: GitHub.