paperclipai/paperclip · error

Slack inventory failed

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.

Solutions

  1. Read the Slack error code in the message and act on it (invalid_auth -> reconnect, missing_scope -> reinstall with scopes, ratelimited -> back off).
  2. Reconnect the Slack connection to refresh the bot token if invalid_auth.
  3. Reinstall the Slack app requesting channels:read and groups:read bot scopes if missing_scope.
  4. Add exponential backoff / reduce request frequency if ratelimited.
  5. 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

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


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/7a5150be03800035. Report an issue: GitHub.

Appendix: 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)