ToolJet/ToolJet · error · QueryError
Refresh token failed
Error message
Refresh token failed
What it means
Thrown in refreshToken() at marketplace/plugins/microsoft_graph/lib/index.ts:419 when the token endpoint POST succeeded (got did not throw) but the parsed response body has no access_token. QueryError('Refresh token failed', 'Access token not found in response', {}). It indicates a 2xx response with an unexpected shape rather than an HTTP error. Note: because this throw sits inside the same try, it is normally re-caught at index.ts:421 and rewrapped as 'Error while generating refresh access token' (error 176).
Source
Thrown at marketplace/plugins/microsoft_graph/lib/index.ts:419
};
const headers = {
'Content-Type': 'application/x-www-form-urlencoded',
};
try {
const response = await got(tokenEndpoint, {
method: 'post',
headers,
form: tokenRequestBody,
responseType: 'json', // Automatically parse JSON response
});
const result = response.body;
if (result['access_token']) {
accessTokenDetails['access_token'] = result['access_token'];
accessTokenDetails['refresh_token'] = result['refresh_token'];
} else {
throw new QueryError('Refresh token failed', 'Access token not found in response', {});
}
} catch (error) {
throw new QueryError('Error while generating refresh access token', JSON.stringify(error), {});
}
return accessTokenDetails;
}
}
View on GitHub (pinned to 20602a8e10)
Solutions
- Log the full response body (the third arg of the resulting QueryError, once re-caught) to see what was returned instead of a token.
- Verify the tokenEndpoint URL is correct for the tenant (https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token).
- If a proxy is intercepting, exclude Microsoft login endpoints or configure got to bypass it.
- Re-authenticate to obtain a fresh refresh_token and retry the exchange.
Example fix
// before: no visibility into a 200-without-token response
if (result['access_token']) { ... } else { throw new QueryError('Refresh token failed', 'Access token not found in response', {}); }
// after: include the unexpected body in the error for diagnostics
if (result['access_token']) { ... } else { throw new QueryError('Refresh token failed', 'Access token not found in response', { body: result }); } Defensive patterns
Strategy: try-catch
Type guard
function hasAccessToken(body: unknown): body is { access_token: string; refresh_token?: string } {
return typeof (body as any)?.access_token === 'string' && (body as any).access_token.length > 0;
} Try / catch
import { QueryError } from '@tooljet-marketplace/common';
try {
await plugin.refreshToken(sourceOptions, dataSourceId, userId, isAppPublic);
} catch (e) {
// error 175 is normally re-caught as 176; detect by description text
if (e instanceof QueryError && /Access token not found in response/i.test(String(e.description))) {
// inspect the response body captured in details, then re-authenticate
} else throw e;
} Prevention
- Log the response body when access_token is missing to detect proxy/conditional-access interference.
- Verify the token endpoint URL matches the tenant.
- Bypass transparent proxies for login.microsoftonline.com.
- Re-authenticate to obtain a fresh refresh_token if the exchange returns an unexpected body.
When it happens
Trigger: Microsoft returns 200 with an error object instead of a token (rare, conditional access or malformed grant handled gracefully by the endpoint); responseType:'json' parsed the body into an object lacking access_token; tenant endpoint returned an unexpected schema; intermediary (proxy) returning a 200 status page.
Common situations: A transparent proxy returning its own 200 HTML/JSON; Azure conditional access returning a challenge body; partial response due to network truncation parsed as valid JSON; tenant misconfiguration routing to a non-token endpoint.
Related errors
- Refresh token not found
- Error while generating refresh access token
- Client Id is required
- Client Secret is required
- Scope is required
AI-assisted analysis of ToolJet/ToolJet@20602a8e10 (2026-08-13).
Data as JSON: /api/errors/12ce9eda37b6574c.
Report an issue: GitHub.