mastra-ai/mastra · error
OAuth failed: ${tokenData.error}
Error message
OAuth failed: ${tokenData.error} What it means
Slack's oauth.v2.access responded HTTP 200 but with ok:false and an error code (e.g. invalid_code, code_already_used, redirect_uri_mismatch, bad_client_secret). The provider throws the Slack-provided error code so the developer can diagnose the OAuth rejection directly.
Source
Thrown at channels/slack/src/provider.ts:1436
redirect_uri: `${baseUrl}/slack/oauth/callback`,
}),
signal: AbortSignal.timeout(30_000),
});
if (!tokenResponse.ok) {
throw new Error(`Slack OAuth HTTP error: ${tokenResponse.status} ${tokenResponse.statusText}`);
}
const tokenData = (await tokenResponse.json()) as {
ok: boolean;
error?: string;
access_token?: string;
bot_user_id?: string;
team?: { id: string; name: string };
};
if (!tokenData.ok) {
throw new Error(`OAuth failed: ${tokenData.error}`);
}
if (!tokenData.access_token || !tokenData.bot_user_id || !tokenData.team?.id) {
throw new Error('Slack OAuth response missing required fields (access_token, bot_user_id, or team)');
}
// Save completed installation (encrypted)
const installation: SlackInstallation = {
id: pending.id,
agentId: pending.agentId,
ownerType: pending.ownerType ?? 'agent',
webhookId: pending.webhookId,
appId: pending.appId,
clientId: pending.clientId,
clientSecret: pending.clientSecret,
signingSecret: pending.signingSecret,
botToken: tokenData.access_token,
botUserId: tokenData.bot_user_id,View on GitHub (pinned to 75dd419e61)
Solutions
- Restart the OAuth flow from the beginning to obtain a fresh code (codes are single-use and short-lived).
- Ensure redirect_uri in the token exchange exactly matches the redirect URL registered in the Slack app settings.
- Verify SLACK_CLIENT_ID/SLACK_CLIENT_SECRET are current and correct (the error code often says bad_client_secret).
- Read the interpolated Slack error code (e.g. invalid_code) and address it specifically.
Example fix
// before
redirect_uri: `${baseUrl}/slack/oauth/callback` // must match Slack app config
// after
// In Slack app settings > OAuth & Permissions, add exactly:
// https://<your-baseUrl>/slack/oauth/callback
// then restart the install flow (do not reuse the code). Defensive patterns
Strategy: try-catch
Try / catch
try {
await handleSlackOAuthCallback(req);
} catch (e) {
const m = /OAuth failed: (.+)/.exec(e.message);
if (m) {
// e.g. code_already_used / invalid_code / redirect_uri_mismatch
return restartOAuthFlow(m[1]);
}
throw e;
} Prevention
- Treat OAuth codes as single-use: never retry the callback with the same code.
- Keep the redirect_uri byte-identical between authorize and token exchange and Slack app settings.
- Rotate client secrets centrally so all environments update together.
When it happens
Trigger: Completing the OAuth callback when Slack rejects the grant: code already redeemed, code expired (>10 min), redirect_uri differing from the initial authorize request, or wrong app credentials.
Common situations: Users double-clicking the authorize button or refreshing the callback URL (code_already_used); mismatched redirect URLs between local dev (http://localhost) and the Slack app config; stale client secret after rotating credentials.
Related errors
- Google user is not in an allowed hosted domain
- Slack refresh token is invalid. Get fresh tokens from https:
- Token rotation failed: ${data.error}
- No Slack installation found for agent "${agentId}"
- SlackProvider baseUrl not available during OAuth callback
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/cff8a433b9d395ca.
Report an issue: GitHub.