CherryHQ/cherry-studio · error · Error

Discord bot token is required

Error message

Discord bot token is required

What it means

Thrown by DiscordAdapter.performConnect during connection start when this.botToken is empty/falsy. checkReady already returns false without a token, so reaching performConnect with no token means the adapter was instructed to connect despite the gateway reporting not-ready — i.e. a connect was forced without configuring bot_token in channelConfig.

Source

Thrown at src/main/ai/channels/adapters/discord/DiscordAdapter.ts:253

  private readonly reconnectDelays = [1000, 2000, 5000, 10000, 30000, 60000]
  private readonly maxReconnectAttempts = 50
  /** Per-chat streaming controller. One stream at a time per chat. */
  private readonly streamingControllers = new Map<string, DiscordStreamingController>()

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

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

  protected override async performConnect(_signal: AbortSignal): Promise<void> {
    if (!this.botToken) throw new Error('Discord bot token is required')
    this.shouldStop = false
    await this.startGateway()
    this.log.info('Discord bot started')
  }

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

  // ─── Gateway Connection ───────────────────────────────────────

  private async getGatewayUrl(): Promise<string> {

View on GitHub (pinned to 726446b54c)

Solutions

  1. Open the Discord channel settings and paste a valid bot token into bot_token, then save.
  2. Validate bot_token is non-empty before calling connect (and surface a setup prompt in the UI).
  3. Keep checkReady gating connect so the adapter is not asked to connect in a not-ready state.
  4. Regenerate the token in the Discord Developer Portal if it was revoked or never created.

Example fix

// before: connect attempted with empty token
await discordAdapter.connect()

// after: guard on readiness
if (await discordAdapter.checkReady()) {
  await discordAdapter.connect()
} else {
  throw new Error('Configure the Discord bot token before connecting')
}
Defensive patterns

Strategy: validation

Validate before calling

if (!adapter.botToken) {
  // surface 'configure Discord bot token' in the UI; do not call connect()
  throw new Error('Configure the Discord bot token before connecting')
}
if (await adapter.checkReady()) {
  await adapter.connect()
}

Type guard

function hasBotToken(config: { bot_token?: string }): boolean {
  return typeof config.bot_token === 'string' && config.bot_token.trim().length > 0
}

Try / catch

try {
  await discordAdapter.connect()
} catch (e) {
  if (e instanceof Error && /Discord bot token is required/.test(e.message)) {
    // mark the Discord channel as 'needs token' in the UI
    logger.warn('Discord connect blocked: missing bot token')
  } else throw e
}

Prevention

When it happens

Trigger: DiscordAdapter.performConnect() runs (channel connect requested) while config.channelConfig.bot_token is empty or undefined.

Common situations: A Discord channel was created/saved without pasting a bot token; the token field was cleared; the channel config was imported/seeded without a token; the user clicked connect before completing setup.

Related errors


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