Skip to content

WhatsApp replies show in WhatsApp but display NO_REPLY in TUI/Web when AI uses message tool #7010

@Morrowind-Xie

Description

@Morrowind-Xie

[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

  1. Configure WhatsApp channel with selfChatMode: true and audio transcription enabled
  2. Send a voice message to your WhatsApp (e.g., Chinese voice: "你好,今天天气怎么样?")
  3. AI processes the message, transcribes via Whisper, and responds using the message tool
  4. Check the response in three places:
    • WhatsApp app: ✅ Reply received
    • TUI (pnpm openclaw chat): ❌ Shows NO_REPLY
    • Web interface (http://127.0.0.1:18789/chat?session=agent%3Amain%3Amain): ❌ Shows NO_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_REPLY instead 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:

  1. Still suppress duplicate channel replies (prevent duplicate WhatsApp messages)
  2. 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 - shouldSuppressMessagingToolReplies
    • src/auto-reply/reply/agent-runner-payloads.ts:115 - Invocation point
    • src/config/types.whatsapp.ts - WhatsApp config (no systemPrompt field)
    • src/config/types.discord.ts:40 - Discord config (has systemPrompt field)
  • The issue is reproducible with voice messages but likely affects all scenarios where the AI uses the message tool 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtuiTerminal UI changes

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions