On this page
On this page
Configuration
Bot loop protection
OpenClaw can accept messages written by other bots on channels that support allowBots. Discord and Slack default to accepting them under the normal mention and access rules; an explicit allowBots: false still disables bot-triggered turns. Bot messages can remain visible as conversation context independently of turn admission.
Pair loop protection bounds rapid exchanges between two bot identities. It is a sliding-window rate guard, so slower exchanges below the budget can continue.
The guard is enforced by the core inbound reply runner. Each supporting channel maps its inbound event into generic facts: account or scope, conversation id, sender bot id, and receiver bot id. Core tracks the participant pair in both directions (A to B and B to A count as the same pair), applies a sliding-window budget, and suppresses the pair during a cooldown after the budget is exceeded.
Defaults
Pair loop protection is active whenever a channel lets bot-authored messages reach dispatch. Built-in defaults:
| Key | Default | Meaning |
|---|---|---|
enabled |
true |
Guard active for channels that support it. |
maxEventsPerWindow |
20 |
Events a bot pair can exchange within the window. |
windowSeconds |
60 |
Sliding window length. |
cooldownSeconds |
60 |
Suppression time after the pair exceeds the budget. |
The guard does not affect human-authored messages, single-bot deployments, self-message filtering, or bot replies that stay under the budget.
Configure shared defaults
Set channels.defaults.botLoopProtection once to give every supporting channel the same baseline. Channels may also expose narrower overrides; Feishu intentionally uses only this shared baseline.
{ channels: { defaults: { botLoopProtection: { maxEventsPerWindow: 20, windowSeconds: 60, cooldownSeconds: 60, }, }, },}Set enabled: false only when your channel policy intentionally allows bot-to-bot conversations without automatic suppression.
Override per channel, account, or room
Supporting channels layer their own config over the shared default, key by key. Precedence, narrowest first:
channels.<channel>.<room-or-space>.botLoopProtection, when the channel supports per-conversation overrideschannels.<channel>.accounts.<account>.botLoopProtection, when the channel supports accountschannels.<channel>.botLoopProtection, when the channel supports top-level defaultschannels.defaults.botLoopProtection- built-in defaults
{ channels: { defaults: { botLoopProtection: { maxEventsPerWindow: 20, }, }, discord: { botLoopProtection: { maxEventsPerWindow: 8, }, accounts: { secondary: { allowBots: true, botLoopProtection: { maxEventsPerWindow: 5, cooldownSeconds: 90, }, }, }, }, googlechat: { allowBots: true, groups: { "spaces/AAAA": { botLoopProtection: { maxEventsPerWindow: 5, }, }, }, }, matrix: { allowBots: "mentions", groups: { "!roomid:example.org": { botLoopProtection: { maxEventsPerWindow: 5, }, }, }, }, slack: { allowBots: "mentions", botLoopProtection: { maxEventsPerWindow: 8, }, }, },}Channel support
- Discord: native
author.botfacts, keyed by Discord account, channel, and bot pair. - Feishu: native
sender_type=botfacts for admitted bot-authored group messages, keyed by Feishu account, chat, and bot pair. Feishu uses onlychannels.defaults.botLoopProtection. - Google Chat: native
sender.type=BOTfacts for accepted bot-authored messages, keyed by account, space, and bot pair. - Matrix: configured Matrix bot accounts, keyed by Matrix account, room, and configured bot pair.
- Slack: native
bot_idfacts for accepted bot-authored messages, keyed by Slack account, channel, and bot pair.
Channels that do not expose a reliable inbound bot identity keep using their normal self-message and access-policy filters. They should not opt into this guard until they can identify both participants in the bot pair.
See SDK runtime for plugin implementation details.
Internal agent group rounds
Agent group threads use a separate coordinator
budget for participants sharing one inbound message. Qualified broadcast
entries allow at most 4 rounds and 32 participant turns. maxRounds includes
the initial round; maxTurns counts agent runs started, with slots reserved
before parallel launch. Every participant passing, either limit, or
cancellation stops further turns.
A participant turn may produce several physical messages through chunking, previews, or message-tool sends. The coordinator does not count those messages. Its in-memory budget is scoped to the channel, account, conversation, thread, and root message, and cannot resume after a Gateway restart.
Internal continuations have distinct identities so ordinary inbound dedupe does not suppress them. They do not change the transport pair guard’s thresholds or replace channel bot-admission and self-message policies. Keep those protections enabled for bot-authored messages arriving from the platform.