FlowiseAI/Flowise · error · Error
Failed to refresh token: ${refreshResponse.status} ${refresh
Error message
Failed to refresh token: ${refreshResponse.status} ${refreshResponse.statusText} - ${errorData} What it means
Thrown when the internal OAuth2 refresh endpoint (POST /api/v1/oauth2-credential/refresh/<id>) responds with a non-2xx status. The message includes status code, status text, and the response body so the upstream refresh failure is visible. The provider itself (Google, Microsoft, GitHub, etc.) rejected the refresh attempt.
Source
Thrown at packages/components/src/utils.ts:1487
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) {
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.`
)
}
}
}View on GitHub (pinned to abe4a8601a)
Solutions
- Read the embedded status + errorData: 400 invalid_grant means re-authorize; 401 means check client credentials.
- Confirm options.baseURL points at the reachable Flowise API (defaults to http://localhost:3000).
- If invalid_grant, re-authorize the OAuth2 credential — the refresh token is no longer usable.
- Verify the OAuth client ID/secret stored in Flowise match the provider console.
- Guard against concurrent refreshes (dedupe by credentialId) to avoid burning single-use refresh tokens.
Example fix
// before
if (!refreshResponse.ok) {
const errorData = await refreshResponse.text()
throw new Error(`Failed to refresh token: ${refreshResponse.status} ${refreshResponse.statusText} - ${errorData}`)
}
// after — classify common provider errors for the caller
if (!refreshResponse.ok) {
const errorData = await refreshResponse.text()
let parsed: any = {}
try { parsed = JSON.parse(errorData) } catch {}
if (refreshResponse.status === 400 && parsed.error === 'invalid_grant') {
throw new Error('Refresh token is invalid or expired — re-authorize the OAuth2 credential.')
}
throw new Error(`Failed to refresh token: ${refreshResponse.status} ${refreshResponse.statusText} - ${errorData}`)
} Defensive patterns
Strategy: try-catch
Validate before calling
function classifyRefreshFailure(status: number, body: string): 'invalid_grant' | 'client' | 'server' | 'unknown' {
let p: any = {}
try { p = JSON.parse(body) } catch {}
if (status === 400 && p.error === 'invalid_grant') return 'invalid_grant'
if (status === 401 || status === 400) return 'client'
if (status >= 500) return 'server'
return 'unknown'
} Type guard
function isProviderGrantError(body: string): boolean {
try { return JSON.parse(body)?.error === 'invalid_grant' } catch { return false }
} Try / catch
if (!refreshResponse.ok) {
const errorData = await refreshResponse.text()
const kind = classifyRefreshFailure(refreshResponse.status, errorData)
if (kind === 'invalid_grant') throw new Error('Refresh token invalid — re-authorize the credential.')
throw new Error(`Failed to refresh token: ${refreshResponse.status} ${refreshResponse.statusText} - ${errorData}`)
} Prevention
- Configure options.baseURL explicitly to the reachable Flowise API.
- Keep OAuth client ID/secret in sync with the provider console.
- Dedupe concurrent refresh requests per credentialId for single-use refresh tokens.
When it happens
Trigger: Provider returns 400 invalid_grant (refresh token revoked, expired, or already used); 401 unauthorized_client (client secret changed); 400 invalid_client (misconfigured client ID/secret in Flowise); network error masqueraded as 5xx; refresh endpoint itself returned 404 because the credentialId doesn't exist.
Common situations: User revoked app access in the provider's account settings; client secret rotated in the provider console but not updated in Flowise; refresh token is single-use and was consumed by a concurrent request; the credential was deleted between the expiry check and the refresh call; Flowise server baseURL misconfigured so the request hits the wrong host.
Related errors
- Access token is expired and no refresh token is available. P
- Failed to refresh access token: ${error instanceof Error ? e
- Oxylabs: Failed to call Oxylabs API: ${response.status}
- Google Sheets API Error ${response.status}: ${response.statu
- Jira API Error ${response.status}: ${response.statusText} -
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/349279a01a7e7021.
Report an issue: GitHub.