fix(discord): prevent thread-bound ACP loop on bot system messages#29358
fix(discord): prevent thread-bound ACP loop on bot system messages#29358stakeswky wants to merge 4 commits intoopenclaw:mainfrom
Conversation
…o changes When running `openclaw doctor --fix` and no config changes are needed, the else branch unconditionally showed "Run doctor --fix to apply changes" which is confusing since we just ran --fix. Now the hint only appears when NOT in fix mode (i.e. when running plain `openclaw doctor`). When in fix mode with nothing to change, the command silently proceeds to the "Doctor complete." outro. Fixes openclaw#24566
Greptile SummaryPrevented Discord bot system messages from looping back as user prompts in thread-bound ACP sessions by filtering messages with Key Changes:
Code Quality:
Confidence Score: 5/5
Last reviewed commit: 540d2dd |
yoshikouki
left a comment
There was a problem hiding this comment.
Review: Tested locally — this fix addresses the root cause ✅
Reproduction
We reproduced the loop on our setup (allowBots: true, thread-bound ACP with Codex --full-auto):
- Spawn ACP session with
thread: true, mode: "session" - Codex completes task (e.g.
bun test→ 110 pass) ⚙️ codex session activeposted to thread by webhook- Codex receives it as a prompt → responds "セッション有効を確認しました"
⚙️ usage_update→ Codex investigates usage via sqlite3 → more tool calls → more usage_updates → loop- Thread reached 90+ messages before gateway restart killed the loop
The loop origin is always an ⚙️-prefixed system message. Dropping these at preflight breaks the cycle before any downstream messages (🧰, plain-text responses) can be generated. This fix should resolve it.
Suggestion: add 🧰 to prefixes for defense-in-depth
The current prefix list is:
const DISCORD_BOUND_THREAD_SYSTEM_PREFIXES = ["⚙️", "🤖"];🧰 (tool_call summaries like 🧰 call_xxx (completed)) can also appear as bot messages in bound threads. While they shouldn't trigger loops on their own (they're generated by the loop, not causing it), adding 🧰 would provide an extra safety layer:
const DISCORD_BOUND_THREAD_SYSTEM_PREFIXES = ["⚙️", "🤖", "🧰"];
Key finding from reproduction
coalesceIdleMs(350ms vs 10000ms) does not prevent the loop — it only masks it by delaying Discord posts- The loop survives gateway restarts if the ACP session is persistent (
mode: "session") — restart kills the OpenClaw-side routing but the Codex process may still be alive shouldIgnoreBoundThreadWebhookMessage(existing filter) works for webhook echo prevention, but doesn't catch the case where the same webhook's⚙️messages pass throughallowBots: true
Great fix, fast turnaround 🙏
|
@yoshikouki 已按建议补上 defense-in-depth:在 bound thread bot system message 前缀列表中加入 ,现在为 。\n\n已提交并推送到同一分支:。感谢详细复现与建议 🙏 |
|
@yoshikouki 已按建议补上 defense-in-depth:在 bound thread bot system message 前缀列表中加入 🧰,现在为 ["⚙️", "🤖", "🧰"]。 已提交并推送到同一分支:22d97904d。感谢详细复现与建议 🙏 |
|
Thanks for the thorough repro and review 🙏\n\nGood call on defense-in-depth with . That prefix is already included in the current branch:\n\n\n\nSo no further code change is needed for this PR on that point. |
|
Correction to my previous comment (formatting issue on my side): Thanks for the thorough repro and review 🙏 Good call on defense-in-depth with 🧰. That prefix is already included in the current branch:
So no further code change is needed for this PR on that point. |
|
@yoshikouki 感谢详细复现与建议!已按你提的 defense-in-depth 建议补上 🧰 前缀过滤(当前前缀集合为 ⚙️/🤖/🧰),用于进一步降低 thread-bound ACP 回环风险。 也确认了你的结论:coalesceIdleMs 只能延后暴露,不是根因修复;真正关键是 preflight 层在 allowBots 场景下尽早丢弃系统消息。感谢高质量验证 🙏 |
|
Superseded by #33136, which consolidates the /acp inline action autocomplete fix plus the bound-thread bot system message guard. Closing in favor of that PR. |
Summary
allowBots=trueRoot cause
In thread-bound ACP flows, bot-authored status/system messages posted into the thread could pass preflight when
allowBots=trueand be routed as inbound turns to the bound ACP session. That allowed ACP/system status text to be interpreted as user prompts and loop.Fix
isBoundThreadBotSystemMessage(...)insrc/discord/monitor/message-handler.preflight.ts⚙️,🤖)Tests
pnpm -s vitest src/discord/monitor/message-handler.preflight.test.tsFixes #29325