mastra-ai/mastra · error

App deletion failed: ${data.error}

Error message

App deletion failed: ${data.error}

What it means

deleteApp calls Slack's app-deletion endpoint and expects ok:true; any ok:false response is converted into this error carrying Slack's error string.

Source

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

    await this.rotateToken();

    const response = await fetch(`${SLACK_API_BASE}/apps.manifest.delete`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${this.#token}`,
      },
      body: JSON.stringify({ app_id: appId }),
      signal: AbortSignal.timeout(SLACK_API_TIMEOUT_MS),
    });

    const data = (await response.json()) as {
      ok: boolean;
      error?: string;
    };

    if (!data.ok) {
      throw new Error(`App deletion failed: ${data.error}`);
    }
  }

  /**
   * Check whether a Slack app still exists.
   *
   * Uses the read-only `apps.manifest.export` endpoint as an existence probe.
   * Returns `false` when Slack reports the app is missing/inaccessible
   * (e.g. it was deleted from the Slack admin UI), `true` when it exports
   * successfully. Network/transport errors are re-thrown so callers can
   * distinguish "app is gone" from "couldn't reach Slack".
   */
  async appExists(appId: string): Promise<boolean> {
    await this.rotateToken();

    const response = await fetch(`${SLACK_API_BASE}/apps.manifest.export`, {
      method: 'POST',
      headers: {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Check the Slack error in the message; if the app was already deleted, treat disconnect as complete and clear local state
  2. Refresh your app configuration tokens from https://api.slack.com/apps and retry
  3. Retry on transient errors; if persistent, verify the appId and token used for deletion are correct

Example fix

// before
await slackClient.deleteApp(appId); // throws if already deleted
// after
try { await slackClient.deleteApp(appId); } catch (e) {
  if (String(e).includes('already_deleted')) return; // idempotent disconnect
  throw e;
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await client.deleteApp(appId);
} catch (e) {
  const msg = (e as Error).message;
  if (msg.startsWith('App deletion failed:')) {
    if (/already/i.test(msg)) return; // treat as idempotent success
    await backoffRetry(() => client.deleteApp(appId));
  } else throw e;
}

Prevention

When it happens

Trigger: deleteApp() (typically invoked during channel disconnect) receives { ok: false, error: <string> } from Slack — e.g. invalid app token, app already deleted, or Slack-side failure.

Common situations: Disconnecting a channel whose app was already deleted manually in Slack; expired/rotated app configuration token; transient Slack API outage during disconnect.

Related errors


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