nexu-io/open-design · error · Error
token endpoint response missing access_token
Error message
token endpoint response missing access_token
What it means
exchangeCodeForToken received a 2xx but the JSON body has no access_token, which a conformant token endpoint must return. Its absence on a success status means a non-standard, errored, or envelope-wrapped response.
Source
Thrown at apps/daemon/src/mcp-oauth.ts:430
// client_id we already put in the form. Public clients (PKCE-only)
// skip this branch.
const basic = Buffer.from(`${form.get('client_id')}:${clientSecret}`).toString('base64');
headers['authorization'] = `Basic ${basic}`;
}
const res = await fetchImpl(tokenEndpoint, {
method: 'POST',
headers,
body: form.toString(),
});
if (!res.ok) {
const txt = await safeText(res);
throw new Error(
`token endpoint rejected request: HTTP ${res.status} ${res.statusText} ${txt}`,
);
}
const json = (await res.json()) as OAuthTokenResponse;
if (!json.access_token) {
throw new Error('token endpoint response missing access_token');
}
return json;
}
async function safeText(res: Response): Promise<string> {
try {
const t = await res.text();
return t.slice(0, 500);
} catch {
return '';
}
}
// ───────────────────────────────────────────────────────────────────────
// In-memory pending-state cache.
// ───────────────────────────────────────────────────────────────────────
/**View on GitHub (pinned to 5be4028344)
Solutions
- Inspect the raw token response body.
- If the provider wraps tokens, add compatibility handling or pre-register a client.
- Confirm you are hitting the true token_endpoint.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await exchangeCodeForToken(tokenEndpoint, params);
} catch (e) {
if (/missing access_token/i.test(e.message)) {
// inspect raw token body; restart beginAuth if the response is malformed
return beginAuth(input);
}
throw e;
} Prevention
- Smoke-test the token endpoint shape against each provider.
- Restart beginAuth on malformed token responses.
- Confirm the endpoint is the true token_endpoint from metadata.
When it happens
Trigger: Provider returned 200 with an error body; returned a wrapped or envelope schema; returned a refresh-only or empty payload.
Common situations: A non-conformant provider; an intermediate proxy rewrote the response.
Related errors
- dynamic client registration response missing client_id
- token endpoint rejected request: HTTP ${res.status} ${res.st
- unsupported brand asset protocol: ${parsed.protocol}
- invalid_generation
- generation_payload_mismatch
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/6bd4982968191fb1.
Report an issue: GitHub.