ToolJet/ToolJet · error · QueryError
Authorization Error
Error message
Authorization Error
What it means
Asana accessDetailsFrom() performs the OAuth token exchange inside try/catch. On any failure it throws QueryError 'Authorization Error' with error.response?.body || error.message and { error: error.message }. This covers the authorization-code → access-token exchange step failing.
Source
Thrown at marketplace/plugins/asana/lib/index.ts:78
const result = JSON.parse(response.body);
const authDetails: [string, string][] = [];
if (result['access_token']) {
authDetails.push(['access_token', result['access_token']]);
}
if (result['refresh_token']) {
authDetails.push(['refresh_token', result['refresh_token']]);
}
if (result['expires_in']) {
authDetails.push(['expires_in', result['expires_in'].toString()]);
}
if (result['token_type']) {
authDetails.push(['token_type', result['token_type']]);
}
return authDetails;
} catch (error) {
throw new QueryError(
'Authorization Error',
error.response?.body || error.message,
{ error: error.message }
);
}
}
async refreshToken(
sourceOptions: SourceOptions,
_dataSourceId?: string,
userId?: string,
isAppPublic?: boolean
): Promise<{ access_token: string; refresh_token?: string }> {
let refreshToken: string;
if (sourceOptions.multiple_auth_enabled) {
const currentToken = sourceOptions.tokenData?.find((t) =>
isAppPublic && !userId ? true : t.user_id === userId
);View on GitHub (pinned to 20602a8e10)
Solutions
- Read error.response.body in the QueryError for Asana's specific OAuth error.
- Restart the OAuth flow to obtain a fresh authorization code.
- Ensure the redirect URI exactly matches the one registered in the Asana app.
- Confirm client_id/client_secret are correct for this environment.
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check: ensure the auth code is present and redirect URI matches the registered app before exchanging.
if (!authCode) throw new Error('Missing authorization code');
if (redirectUri !== registeredRedirectUri) throw new Error('Redirect URI mismatch'); Try / catch
try {
return await asana.accessDetailsFrom(authCode, source_options);
} catch (e) {
if (e?.message === 'Authorization Error') {
const body = e?.data?.error;
if (/invalid_grant|code/i.test(body)) promptReauthorize();
else if (/redirect_uri/i.test(body)) notifyAdmin('Redirect URI mismatch in Asana app config.');
else notifyUser('Asana authorization failed: ' + body);
} else throw e;
} Prevention
- Use each authorization code exactly once.
- Keep the redirect URI identical in the datasource and the Asana app.
- Restart the OAuth flow on invalid_grant rather than retrying the same code.
When it happens
Trigger: Invalid/expired authorization code. Redirect URI mismatch with the registered Asana app. Wrong client_secret/client_id. Code already exchanged (reuse). Network error hitting the Asana token endpoint.
Common situations: User retried the OAuth flow with a stale code. Redirect URI configured differently in the Asana app vs the datasource. Clock skew or token endpoint outage.
Related errors
- Refresh token not found
- Refresh token failed
- Asana OAuth client_id is missing
- MISSING_FIELDS
- INVALID_SPEC_TYPE
AI-assisted analysis of ToolJet/ToolJet@20602a8e10 (2026-08-13).
Data as JSON: /api/errors/1c60e14fd285aa4d.
Report an issue: GitHub.