Skip to content

Telegram: setMyCommands fails with BOT_COMMANDS_TOO_MUCH when skills exceed 100 command limit #5787

@battman21

Description

@battman21

OpenClaw registers all user-invocable skills as Telegram bot commands via setMyCommands, but doesn't enforce Telegram's 100 command limit. With 52+ bundled skills plus custom agent skills, this easily exceeds the limit, causing repeated failures on every gateway startup.

Reproduction

  1. Install OpenClaw with default bundled skills (52+)
  2. Add a few agents with custom skills
  3. Connect Telegram channel
  4. Observe logs on startup:
[telegram] [default] starting provider (@jbiggles_bot)
[telegram] setMyCommands failed: Call to 'setMyCommands' failed! (400: Bad Request: BOT_COMMANDS_TOO_MUCH)

Expected Behavior

OpenClaw should either:

  • Respect Telegram's 100 command limit by prioritizing/truncating commands
  • Not register skills as Telegram commands by default (agent handles via natural language)
  • Warn users when command count exceeds the limit

Actual Behavior

  • setMyCommands fails silently (caught and ignored)
  • Error repeats on every startup and config reload
  • Bot menu shows no commands (or stale commands)
  • No warning to user about the limit being exceeded

Environment

  • OpenClaw version: 2026.1.29
  • Platform: Linux (Docker)
  • Skills: 52 bundled + ~30 custom across 5 agents

Analysis

Telegram API limit: Telegram Bot API docs state setMyCommands accepts "at most 100 commands".

No limit enforcement in OpenClaw: In src/telegram/bot-native-commands.ts:325-339:

const allCommands: Array<{ command: string; description: string }> = [
  ...nativeCommands.map((command) => ({
    command: command.name,
    description: command.description,
  })),
  ...pluginCommands,
  ...customCommands,
];

if (allCommands.length > 0) {
  withTelegramApiErrorLogging({
    operation: "setMyCommands",
    runtime,
    fn: () => bot.api.setMyCommands(allCommands),  // No limit check
  }).catch(() => {});

Default registers ALL skills: listSkillCommandsForAgents() returns every skill where userInvocable !== false across all agents - no Telegram-specific filtering.

Suggested Fix

Option A: Enforce limit with prioritization

const TELEGRAM_MAX_COMMANDS = 100;

const allCommands = [
  ...nativeCommands,  // Priority 1: native commands
  ...pluginCommands,  // Priority 2: plugin commands
  ...customCommands,  // Priority 3: user custom commands
];

if (allCommands.length > TELEGRAM_MAX_COMMANDS) {
  runtime.warn?.(
    `Telegram limits bots to ${TELEGRAM_MAX_COMMANDS} commands. ` +
    `${allCommands.length} commands configured; registering first ${TELEGRAM_MAX_COMMANDS}. ` +
    `Set channels.telegram.commands.native: false to disable, or use channels.telegram.commands.skills: [] to filter.`
  );
}

const commandsToRegister = allCommands.slice(0, TELEGRAM_MAX_COMMANDS);

Option B: Don't register skills as commands by default

Add opt-in for skill command registration via SKILL.md frontmatter:

---
telegram-command: true  # Explicitly opt-in to Telegram menu
---

Most skills work perfectly via natural language - the agent reads SKILL.md and executes appropriately. Telegram command menu registration should be opt-in, not automatic.

Option C: Add config to control skill command registration

{
  channels: {
    telegram: {
      commands: {
        native: true,           // existing
        skills: false,          // NEW: disable skill commands (default: true for backwards compat)
        // or whitelist:
        skills: ["weather", "canvas", "summarize"],
        maxCommands: 100,       // NEW: explicit limit with warning
      }
    }
  }
}

Workaround

Until fixed, users can disable native command registration:

{
  channels: {
    telegram: {
      commands: {
        native: false
      },
      customCommands: []
    }
  }
}

This clears the command menu entirely. Agent still handles all skills via natural language.

Impact

  • Severity: Medium - bot still functions, but command menu broken
  • Frequency: Every startup/reload for users with many skills
  • User confusion: No indication why commands aren't appearing

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions