paperclipai/paperclip · error
Slack inventory failed: ${body.error ?? "unknown error"}
Error message
Slack inventory failed: ${body.error ?? "unknown error"} What it means
Thrown by listSlackBotChannels when Slack's conversations.list responds with ok:false — Slack's standard envelope for a failed API call. The thrown message includes body.error (Slack's machine-readable error code like 'invalid_auth', 'missing_scope', 'ratelimited') or 'unknown error' if absent. Only channels where the bot is an active member are listed, so this error concerns the API call itself, not the filtering.
Source
Thrown at server/src/services/chat-provider-inventory.ts:92
const response = await input.fetch(url, {
headers: { authorization: `Bearer ${input.botToken}` },
signal: slackRequestSignal(),
});
const body = await jsonResponse<{
ok?: boolean;
error?: string;
channels?: Array<{
id?: string;
name?: string;
is_member?: boolean;
is_private?: boolean;
is_archived?: boolean;
context_team_id?: string;
}>;
response_metadata?: { next_cursor?: string };
}>(response, "Slack");
if (!body.ok)
throw new Error(
`Slack inventory failed: ${body.error ?? "unknown error"}`,
);
for (const channel of body.channels ?? []) {
if (!channel.id || !channel.is_member || channel.is_archived) continue;
resources.push({
providerResourceId: channel.id,
type: "channel",
label: channel.name ? `#${channel.name}` : channel.id,
metadata: {
private: channel.is_private === true,
...(channel.context_team_id
? { contextTeamId: channel.context_team_id }
: {}),
source: "provider_inventory",
},
});
}
cursor = body.response_metadata?.next_cursor?.trim() ?? "";View on GitHub (pinned to 01ad858492)
Solutions
- Read the Slack error code in the message and act on it (invalid_auth -> reconnect, missing_scope -> reinstall with scopes, ratelimited -> back off).
- Reconnect the Slack connection to refresh the bot token if invalid_auth.
- Reinstall the Slack app requesting channels:read and groups:read bot scopes if missing_scope.
- Add exponential backoff / reduce request frequency if ratelimited.
- Check Slack API status for incidents.
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate token + scopes before calling conversations.list:
const auth = await fetch('https://slack.com/api/auth.test', {
method: 'POST', headers: { Authorization: `Bearer ${botToken}` },
}).then(r => r.json());
if (!auth.ok) throw new Error(`Slack token invalid: ${auth.error}`); Type guard
function isSlackOkBody<T>(b: T & { ok?: boolean }): b is T & { ok: true } {
return (b as { ok?: boolean }).ok === true;
} Try / catch
try { const channels = await listSlackBotChannels(input); }
catch (e) {
const err = /Slack inventory failed: (\S+)/.exec(e.message)?.[1];
if (err === 'ratelimited') await sleep(backoff);
else if (err === 'invalid_auth') await reconnectSlack();
else if (err === 'missing_scope') await reinstallSlackApp(['channels:read','groups:read']);
} Prevention
- Request channels:read and groups:read bot scopes at install time.
- Rotate/refresh bot tokens proactively and reconnect on invalid_auth.
- Throttle conversations.list pagination to respect Slack rate-limit tiers.
- Check Slack API status during outages.
When it happens
Trigger: Slack conversations.list returns {ok:false,...}: invalid_auth (bad/expired bot token), missing_scope (bot lacks channels:read/groups:read), ratelimited, or any other Slack error code.
Common situations: Bot token rotated or revoked by a Slack admin; app reinstalled without read scopes; bulk inventory scans triggering Slack's tier-based rate limits; workspace app restrictions.
Related errors
- ${provider} inventory failed: ${message}
- "configJson" is required and must be an object
- invalid_provider
- Failed to seed CEO instructions:
- ${errorMessage(error)} Cleanup also failed for newly-created
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/7a5150be03800035.
Report an issue: GitHub.