CherryHQ/cherry-studio · error · Error

Slack bot token (xoxb-...) is required

Error message

Slack bot token (xoxb-...) is required

What it means

Thrown by SlackAdapter.performConnect() when bot_token is missing. Slack requires a bot token (xoxb-) to call Web API methods like auth.test (fetchBotUserId) and to identify the bot. The guard fails fast before any Slack call.

Source

Thrown at src/main/ai/channels/adapters/slack/SlackAdapter.ts:227

  private readonly streamingControllers = new Map<string, SlackStreamingController>()
  /** Track the latest incoming message ts per chatId for reaction acknowledgment */
  private readonly pendingReactions = new Map<string, string>()

  constructor(config: ChannelAdapterConfig<'slack'>) {
    super(config)
    const { bot_token, app_token, allowed_channel_ids } = config.channelConfig
    this.botToken = bot_token
    this.appToken = app_token
    this.allowedChannelIds = allowed_channel_ids ?? []
    this.notifyChatIds = [...this.allowedChannelIds]
  }

  protected override async checkReady(): Promise<boolean> {
    return !!(this.botToken && this.appToken)
  }

  protected override async performConnect(_signal: AbortSignal): Promise<void> {
    if (!this.botToken) throw new Error('Slack bot token (xoxb-...) is required')
    if (!this.appToken) throw new Error('Slack app-level token (xapp-...) is required for Socket Mode')
    this.shouldStop = false
    await this.fetchBotUserId()
    await this.startSocketMode()
    this.log.info('Slack bot started')
  }

  protected override async performDisconnect(): Promise<void> {
    this.shouldStop = true
    for (const controller of this.streamingControllers.values()) {
      controller.dispose()
    }
    this.streamingControllers.clear()
    this.pendingReactions.clear()
    this.cleanup()
    this.log.info('Slack bot stopped')
  }

View on GitHub (pinned to 726446b54c)

Solutions

  1. From the Slack App's OAuth & Permissions page, install the app to the workspace and copy the Bot User OAuth Token (starts with xoxb-).
  2. Paste it into channelConfig.bot_token and re-attempt connect.
  3. Ensure the token starts with 'xoxb-' (a different prefix like xapp- belongs in app_token).
  4. Rely on checkReady() (requires both botToken and appToken) to keep the adapter 'not ready' until configured.
Defensive patterns

Strategy: validation

Validate before calling

// Validate tokens before allowing connect.
function slackTokensPresent(cfg: SlackChannelConfig): boolean {
  return Boolean(cfg.bot_token?.startsWith('xoxb-') && cfg.app_token?.startsWith('xapp-'))
}

Type guard

function isSlackMissingBotToken(e: unknown): e is Error {
  return e instanceof Error && e.message === 'Slack bot token (xoxb-...) is required'
}

Try / catch

if (!slackTokensPresent(cfg)) { showConfigError('Provide Slack xoxb- and xapp- tokens'); return }
try { await slack.connect() } catch (e) {
  if (isSlackMissingBotToken(e)) { showConfigError('Provide the Slack bot token (xoxb-)'); return }
  throw e
}

Prevention

When it happens

Trigger: Channel config's channelConfig.bot_token is empty/undefined; performConnect throws immediately, before fetchBotUserId() and startSocketMode().

Common situations: User added a Slack channel but only supplied the app-level token (xapp-), or copied the wrong token type, or the config value didn't persist.

Related errors


AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12). Data as JSON: /api/errors/c0d076d83fd658bb. Report an issue: GitHub.