discordjs/discord.js · error · Error
JSON.stringify(response)
Error message
JSON.stringify(response)
What it means
After a 200 response, authorize() parses the JSON and throws JSON.stringify(response) if the body has no access_token field. The error message is the serialized Response object, which is nearly useless for debugging — the token endpoint replied successfully but not with a token payload.
Source
Thrown at packages/rpc/src/client.ts:375
}
const response = await fetch(`${RouteBases.api}${Routes.oauth2TokenExchange()}`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams(jsonBody),
...options,
});
if (!response.ok) {
throw new Error(response.statusText);
}
const data = (await response.json()) as RESTPostOAuth2AccessTokenResult;
if (!('access_token' in data)) {
throw new Error(JSON.stringify(response));
}
return data.access_token;
}
/**
* Authenticate
*
* @param accessToken - access token
*/
public async authenticate(accessToken: string, options?: RequestOptions): Promise<this> {
const { application, user } = await this.request(RPCCommands.Authenticate, { access_token: accessToken }, options);
this.accessToken = accessToken;
this.application = application;
this.user = user;
this.emit(Events.ApplicationReady);
return this;
}View on GitHub (pinned to a81ed8a306)
Solutions
- Obtain a fresh authorization code and retry the exchange
- Inspect the actual response body (catch and re-fetch) to see the error field Discord returned
- Verify client_id, client_secret, grant_type, and redirect_uri exactly match the authorize step
Example fix
// before
try { await client.login({ clientId, clientSecret, scopes }); }
catch (e) { console.log(e.message); } // prints serialized Response
// after
try { await client.login({ clientId, clientSecret, scopes }); }
catch (e) { console.error('No access_token in token response — check code freshness and grant params'); } Defensive patterns
Strategy: try-catch
Type guard
function hasAccessToken(d: unknown): d is { access_token: string } {
return typeof d === 'object' && d !== null && 'access_token' in d;
} Try / catch
try {
await client.login({ clientId, clientSecret, scopes });
} catch (err) {
// library stringifies the Response; treat as 'token missing in response'
console.error('Token response lacked access_token — request a fresh authorization code');
} Prevention
- Never reuse authorization codes (invalid_grant returns token-less bodies)
- Log the raw token endpoint body during development to see Discord's error field
- Match grant_type and redirect_uri exactly with the authorize request
When it happens
Trigger: Discord returns 200 with an error-shaped JSON body (e.g. { error: 'invalid_grant' }) or an unexpected body during the token exchange in login().
Common situations: Reusing an already-consumed authorization code (invalid_grant), scope/redirect mismatch returning an error body with 200, or a proxy stripping the body.
Related errors
- response.statusText
- HTTPError(status, res.statusText, method, url, requestData)
- A client secret must be provided for authorization if scopes
AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30).
Data as JSON: /api/errors/2e85afde19a17f3b.
Report an issue: GitHub.