usebruno/bruno · error · Error
No access token received from server
Error message
No access token received from server
What it means
Thrown when the token endpoint returned a 2xx response that parsed cleanly and contained no 'error' field, but the body had no access_token. The helper cannot proceed because there is no credential to return or store.
Source
Thrown at packages/bruno-requests/src/auth/oauth2-helper.ts:386
// Otherwise, proceed to fetch new token
}
let tokenResponse;
if (grantType === 'client_credentials') {
tokenResponse = await fetchTokenClientCredentials(oauth2Config, axiosInstance);
} else if (grantType === 'password') {
tokenResponse = await fetchTokenPassword(oauth2Config, axiosInstance);
} else {
throw new Error(`Unsupported grant type: ${grantType}`);
}
if (tokenResponse.error) {
throw new Error(JSON.stringify(tokenResponse));
}
if (!tokenResponse || !tokenResponse.access_token) {
throw new Error('No access token received from server');
}
if (tokenResponse.expires_in && tokenResponse.created_at) {
tokenResponse.expires_at = tokenResponse.created_at + tokenResponse.expires_in * 1000;
}
const saved = await tokenStore.saveCredential({ url: accessTokenUrl, credentialsId, credentials: tokenResponse });
if (!saved) {
console.warn('OAuth2: Failed to save token to store, but proceeding with token');
}
return tokenSource === 'id_token' ? tokenResponse.id_token : tokenResponse.access_token;
};
View on GitHub (pinned to 9bdd81c7bd)
Solutions
- Inspect the raw token response (add logging before the helper or capture network traffic) to see what body the server actually returns.
- If the server uses a non-standard key, normalize the response before relying on this helper, or open a provider-compatibility issue.
- Confirm you are not hitting an HTML login page (200 + HTML) because the token URL points at the wrong endpoint.
- If only an id_token is issued, set tokenSource:'id_token' — but note this error still fires because the access_token check happens first.
Example fix
// before
const config = { grantType: 'client_credentials', accessTokenUrl: url, clientId: id, clientSecret: secret };
// tokenResponse from server = { accessToken: '...' } // non-standard key
// after — point at the correct token endpoint that returns RFC6749 { access_token, token_type, expires_in } Defensive patterns
Strategy: try-catch
Validate before calling
// Cannot prevent from client side; pre-validate the URL points at the real token endpoint:
try { new URL(config.accessTokenUrl); } catch { throw new Error('accessTokenUrl is not a valid URL'); } Try / catch
try { await getOAuth2AccessToken(config, tokenStore); }
catch (e) {
if (e.message === 'No access token received from server') {
// capture the raw response separately to inspect its shape
console.error('Token endpoint did not return access_token; verify RFC6749 compliance');
} else throw e;
} Prevention
- Confirm the token endpoint is the OAuth2 token URL, not a login page or JSON:API endpoint.
- If the server returns a non-standard key, file a provider-compatibility issue or wrap the response.
- Set tokenSource to 'id_token' only if the server actually issues id_tokens.
When it happens
Trigger: Token server returned 200 with an unexpected body shape (e.g. returned only an id_token, or returned the token under a non-standard key like 'accessToken'), or returned an empty object.
Common situations: Server misconfiguration returning the token under a camelCase key instead of access_token; partial response truncated by a proxy; the server issued only an id_token but tokenSource was left at its default 'access_token'; OAuth2 provider returning a non-RFC6749 compliant body.
Related errors
- ${JSON.stringify(tokenResponse)}
- ${response.error}
- Failed to minify
- credentialId must be a non-empty string
- getRandomValues: Constructor ${obj.type} is not available
AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13).
Data as JSON: /api/errors/3a470ef62e02c966.
Report an issue: GitHub.