-
-
Notifications
You must be signed in to change notification settings - Fork 39.6k
Description
[Bug]: WhatsApp replies show in WhatsApp but display NO_REPLY in TUI/Web when AI uses message tool
Summary
When the AI responds to WhatsApp messages using the message tool, the reply is successfully delivered to WhatsApp, but the TUI and Web interfaces display NO_REPLY instead of showing the message content. This breaks the multi-interface consistency that OpenClaw is designed to provide.
Steps to reproduce
- Configure WhatsApp channel with
selfChatMode: trueand audio transcription enabled - Send a voice message to your WhatsApp (e.g., Chinese voice: "你好,今天天气怎么样?")
- AI processes the message, transcribes via Whisper, and responds using the
messagetool - Check the response in three places:
- WhatsApp app: ✅ Reply received
- TUI (
pnpm openclaw chat): ❌ ShowsNO_REPLY - Web interface (
http://127.0.0.1:18789/chat?session=agent%3Amain%3Amain): ❌ ShowsNO_REPLY
Expected behavior
All three interfaces (WhatsApp, TUI, Web) should display the same reply content synchronously. Users should be able to view the conversation history in any interface.
Actual behavior
- WhatsApp app: Receives the AI reply successfully (e.g., "🗣️ 识别结果:"艾伦,今天天气怎么样?" 🌤️ 上海当前天气:⛅️ +10°C")
- TUI/Web: Shows
NO_REPLYinstead of the actual message content
Additional issue when trying to fix with tools.deny
When attempting to fix this by adding tools.deny: ["message"] to the config:
{
"tools": {
"deny": ["message"]
}
}The AI still attempts to call the message tool, resulting in:
[openclaw] ⚠️ ✉️ Message: send · +1234567890 failed: Tool message not found
This suggests the message tool is required for core functionality and cannot be gracefully disabled.
Root cause analysis
Phase 1: Anti-duplicate mechanism
The shouldSuppressMessagingToolReplies function in src/auto-reply/reply/reply-payloads.ts detects when the AI sends a message via the message tool to the originating channel. To prevent duplicate messages, it suppresses standard reply payloads:
const suppressMessagingToolReplies = shouldSuppressMessagingToolReplies({
messageProvider: params.messageProvider,
messagingToolSentTargets,
originatingTo: params.originatingTo,
accountId: params.accountId,
});
const replyPayloads = suppressMessagingToolReplies ? [] : filteredPayloads;Result: WhatsApp receives the tool-sent message, but TUI/Web get empty payloads → NO_REPLY
Phase 2: Tool dependency
When message tool is denied, the AI still attempts to invoke it but receives an error instead of gracefully falling back to direct replies.
Environment
- OpenClaw version: 2026.1.30 (inferred from logs)
- OS: Linux (Arch-based)
- Install method: pnpm
- Channel: WhatsApp Web (via Baileys)
- AI Model: deepseek/deepseek-reasoner
- Audio transcription: Whisper medium model (local)
Configuration
{
"channels": {
"whatsapp": {
"dmPolicy": "allowlist",
"selfChatMode": true,
"allowFrom": ["+1234567890"], // Your phone number
"mediaMaxMb": 50,
"debounceMs": 0
}
},
"tools": {
"media": {
"audio": {
"enabled": true,
"models": [{
"command": "/home/morrowind/whisper-venv/bin/whisper",
"args": ["--model", "medium", "--language", "zh", ...]
}]
}
}
}
}Logs or screenshots
Successful message tool usage (WhatsApp receives reply)
{
"subsystem": "agent/embedded",
"message": "Tracking pending messaging text: tool=message len=318"
}
{
"module": "web-auto-reply",
"message": "sending message to +1234567890"
}
{
"subsystem": "agent/embedded",
"message": "Committed messaging text: tool=message len=318"
}When tool is denied (error instead of fallback)
{
"subsystem": "agent/embedded",
"message": "embedded run tool start: tool=message toolCallId=call_00_jWaFB1unVOrVwBD5vb7TFG0Z"
}
{
"subsystem": "agent/embedded",
"message": "embedded run tool end: tool=message toolCallId=call_00_jWaFB1unVOrVwBD5vb7TFG0Z"
}
{
"module": "web-auto-reply",
"text": "[openclaw] ⚠️ ✉️ Message: send · +1234567890 failed: Tool message not found"
}Proposed solutions
Option 1: Sync to session history (recommended)
Modify shouldSuppressMessagingToolReplies to:
- Still suppress duplicate channel replies (prevent duplicate WhatsApp messages)
- But also copy the message content to the session history (so TUI/Web can display it)
This maintains the anti-duplicate mechanism while ensuring interface consistency.
Option 2: Add WhatsApp systemPrompt support
Currently, only Discord/Slack/Telegram channels support the systemPrompt configuration field (per-channel). Adding this to WhatsApp would allow users to instruct the AI:
{
"channels": {
"whatsapp": {
"systemPrompt": "When replying to messages, respond directly with text. Only use the 'message' tool when explicitly asked to send messages to different contacts or channels."
}
}
}Option 3: Improve tool deny fallback
When a tool is denied via tools.deny, the system should gracefully fallback to alternative behavior instead of returning a "Tool not found" error.
Additional context
- Detailed debugging log: [Attached as comment or external link]
- Related files:
src/auto-reply/reply/reply-payloads.ts:87-123-shouldSuppressMessagingToolRepliessrc/auto-reply/reply/agent-runner-payloads.ts:115- Invocation pointsrc/config/types.whatsapp.ts- WhatsApp config (nosystemPromptfield)src/config/types.discord.ts:40- Discord config (hassystemPromptfield)
- The issue is reproducible with voice messages but likely affects all scenarios where the AI uses the
messagetool to reply
Note: This issue was discovered during Chinese voice message transcription testing with local Whisper integration. The audio transcription works perfectly, but the reply synchronization is broken across interfaces.