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
- Check the Slack error in the message; if the app was already deleted, treat disconnect as complete and clear local state
- Refresh your app configuration tokens from https://api.slack.com/apps and retry
- 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
- Make disconnect flows idempotent — apps may already be deleted
- Retry transient failures with backoff
- Keep app configuration tokens fresh
- Log the Slack error string for diagnosis
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
- Token rotation failed: ${data.error}
- App creation failed: ${errorDetails}
- Failed to check whether Slack app exists: ${data.error ?? 'u
- SlackProvider not attached to Mastra. Call __attach() first.
- MastraAuthBetterAuth is not initialized — init() must run fi
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/a7f3393efb619b7c.
Report an issue: GitHub.