mastra-ai/mastra · critical

Slack refresh token is invalid. Get fresh tokens from https:

Error message

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.

What it means

The Slack channel client rotates OAuth access tokens using a stored refresh token. When Slack responds with error 'invalid_refresh_token', the stored refresh token is no longer usable — it may have been consumed by a prior rotation or lost when storage was wiped. The client throws this explicit message to tell the operator to re-fetch tokens from the Slack app config.

Source

Thrown at channels/slack/src/client.ts:85

      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: new URLSearchParams({
        refresh_token: this.#refreshToken,
      }),
      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

  1. Go to https://api.slack.com/apps > Your App Configuration Tokens and generate fresh tokens, then update them in your storage/config
  2. Ensure only one app instance performs rotation (avoid concurrent rotations consuming one-time refresh tokens)
  3. Verify the storage backend persists tokens across restarts and that you are not pointing at an empty/stale store

Example fix

// before
// storage lost tokens; rotation fails with invalid_refresh_token
// after
await slackClient.setTokens(newAccessToken, newRefreshToken); // fresh tokens from Slack app config
Defensive patterns

Strategy: retry

Validate before calling

const refreshToken = await storage.get('slack_refresh_token');
if (!refreshToken || refreshToken.length < 20) {
  promptOperatorForFreshTokens(); // avoid guaranteed invalid_refresh_token
}

Try / catch

try {
  await client.rotateToken();
} catch (e) {
  if ((e as Error).message.startsWith('Slack refresh token is invalid')) {
    // only recovery: fetch fresh tokens from https://api.slack.com/apps and store them
  } else throw e;
}

Prevention

When it happens

Trigger: #doRotateToken POSTs to Slack's token rotation endpoint and receives { ok: false, error: 'invalid_refresh_token' } — i.e. rotateToken() was invoked (usually after an access token expired) while the persisted refresh token was wrong, empty, or already used.

Common situations: Slack's one-time-use refresh tokens with multiple app instances racing to rotate; wiping/resetting the storage layer (KV/DB) that held the tokens; restoring an old backup with stale tokens; rotating manually in the Slack dashboard so the stored token was invalidated.

Understand the failure class

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/84c861137f44c4de. Report an issue: GitHub.