mastra-ai/mastra · error
Token rotation failed: ${data.error}
Error message
Token rotation failed: ${data.error} What it means
This is the generic failure branch of Slack token rotation: the API responded with ok:false and an error string that is not the special-cased invalid_refresh_token. The client surfaces Slack's own error verbatim in the message.
Source
Thrown at channels/slack/src/client.ts:90
}),
signal: AbortSignal.timeout(SLACK_API_TIMEOUT_MS),
});
const data = (await response.json()) as {
ok: boolean;
error?: string;
token?: string;
refresh_token?: string;
};
if (!data.ok) {
if (data.error === 'invalid_refresh_token') {
throw new Error(
'Slack refresh token is invalid. Get fresh tokens from https://api.slack.com/apps > "Your App Configuration Tokens". ' +
'This can happen if storage was lost or the token was already used.',
);
}
throw new Error(`Token rotation failed: ${data.error}`);
}
if (!data.token || !data.refresh_token) {
throw new Error('Token rotation returned incomplete data');
}
this.#token = data.token;
this.#refreshToken = data.refresh_token;
if (this.#onTokenRotation) {
await this.#onTokenRotation({
token: this.#token,
refreshToken: this.#refreshToken,
});
}
}
/**View on GitHub (pinned to 75dd419e61)
Solutions
- Read the Slack error in the message and act on it (e.g. expired_refresh_token → get fresh tokens from the Slack app config)
- Add retry with backoff for transient errors (rateLimited, server errors) in your wrapper around the channel client
- Verify the app's client ID/secret and that stored tokens are current; re-install the app if rotation is permanently broken
Example fix
// before
try { await client.rotateToken(); } catch (e) { /* unhandled */ }
// after
try { await client.rotateToken(); } catch (e) {
logger.error({ err: e }, 'slack token rotation failed');
if (isTransient(e)) await retryWithBackoff(() => client.rotateToken());
else await alertOperatorForReinstall();
} Defensive patterns
Strategy: retry
Try / catch
try {
await client.rotateToken();
} catch (e) {
const msg = (e as Error).message;
if (msg.startsWith('Token rotation failed:') && /rateLimited|temporarily|server/i.test(msg)) {
await backoffRetry(() => client.rotateToken(), 3);
} else if (msg.startsWith('Slack refresh token is invalid')) {
await alertForFreshTokens();
} else throw e;
} Prevention
- Wrap rotation with exponential backoff for transient Slack errors
- Monitor and log the specific Slack error code from the message
- Keep client credentials and stored tokens current
- Subscribe to Slack API status/changelog
When it happens
Trigger: #doRotateToken receives { ok: false, error: <some error> } from Slack's rotation endpoint (e.g. expired_refresh_token, invalid_client, rateLimited) during rotateToken().
Common situations: Expired refresh tokens after long downtime; wrong client credentials/env in the rotation request; Slack API rate limits or transient outages; malformed stored tokens after manual DB edits.
Related errors
- Slack refresh token is invalid. Get fresh tokens from https:
- Token rotation returned incomplete data
- App creation failed: ${errorDetails}
- App deletion failed: ${data.error}
- Failed to check whether Slack app exists: ${data.error ?? 'u
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/4f0134e33c18969b.
Report an issue: GitHub.