Summary
When OpenClaw sends a WhatsApp message from the Gateway to the linked account's own WhatsApp number, openclaw channels status --json can report that WhatsApp inbound activity also advanced.
This makes channels status --probe / status JSON look like a real inbound WhatsApp message was handled even though the Gateway only performed an outbound send and the logs show no inbound message handling.
Environment
- OS: Ubuntu 24.04
- OpenClaw: current main at
95a1c91531
- Runtime: Node 22
- Gateway: managed systemd user service
- Channel: WhatsApp Web, linked account
default
- Auth/config: live WhatsApp account, private phone numbers redacted
Reproduction
- Start a linked WhatsApp Gateway account and verify it is healthy.
OPENCLAW_HIDE_BANNER=1 openclaw channels status --probe
- Capture the current WhatsApp account status.
BEFORE="$(OPENCLAW_HIDE_BANNER=1 openclaw channels status --json)"
- Resolve the linked WhatsApp account's own E.164 number.
TARGET="$(
OPENCLAW_HIDE_BANNER=1 openclaw gateway health --json \
| node -e 'let s="";process.stdin.on("data",d=>s+=d);process.stdin.on("end",()=>{const j=JSON.parse(s); console.log(j.channels?.whatsapp?.self?.e164 || "")})'
)"
- Send one Gateway-originated WhatsApp message to that same number.
MARKER="OpenClaw WhatsApp inbound-status echo repro $(date -u +%Y%m%dT%H%M%SZ)"
SEND="$(OPENCLAW_HIDE_BANNER=1 openclaw message send --channel whatsapp --account default --target "$TARGET" --message "$MARKER" --json)"
sleep 8
AFTER="$(OPENCLAW_HIDE_BANNER=1 openclaw channels status --json)"
- Compare the WhatsApp account
lastInboundAt and lastOutboundAt fields before/after.
node - <<'NODE' "$BEFORE" "$SEND" "$AFTER" "$MARKER"
const [beforeRaw, sendRaw, afterRaw, marker] = process.argv.slice(2);
const before = JSON.parse(beforeRaw);
const send = JSON.parse(sendRaw);
const after = JSON.parse(afterRaw);
function acct(j){ return j.channelAccounts?.whatsapp?.[0] ?? {}; }
function iso(ms){ return typeof ms === "number" ? new Date(ms).toISOString() : null; }
const b = acct(before);
const a = acct(after);
console.log(JSON.stringify({
marker,
sendMessageId: send.payload?.result?.messageId,
before: { lastInboundAt: iso(b.lastInboundAt), lastOutboundAt: iso(b.lastOutboundAt) },
after: { lastInboundAt: iso(a.lastInboundAt), lastOutboundAt: iso(a.lastOutboundAt) },
inboundAdvanced: (a.lastInboundAt ?? 0) > (b.lastInboundAt ?? 0),
outboundAdvanced: (a.lastOutboundAt ?? 0) > (b.lastOutboundAt ?? 0)
}, null, 2));
NODE
Expected behavior
For a Gateway-originated WhatsApp self-send:
lastOutboundAt should advance.
lastInboundAt should not advance unless a real inbound WhatsApp message is accepted and handled.
- Logs should show an outbound send only.
Actual behavior
Both timestamps advanced for a single Gateway-originated self-send:
{
"marker": "OpenClaw WhatsApp inbound-status echo repro 20260507T174110Z",
"sendMessageId": "3EB03B031C04B624AAEA9B",
"before": {
"lastInboundAt": "2026-05-07T17:18:40.619Z",
"lastOutboundAt": "2026-05-07T17:18:40.517Z"
},
"after": {
"lastInboundAt": "2026-05-07T17:41:18.191Z",
"lastOutboundAt": "2026-05-07T17:41:18.145Z"
},
"inboundAdvanced": true,
"outboundAdvanced": true
}
The matching redacted Gateway logs showed only outbound send activity for the marker window:
[whatsapp] Sending message -> sha256:<redacted>
[whatsapp] Sent message 3EB03B031C04B624AAEA9B -> sha256:<redacted>
[ws] res send channel=whatsapp
No Inbound message, web-inbound, or web-auto-reply log line appeared for the marker.
Why this matters
openclaw channels status --probe and the status JSON are used as live channel-health and activity diagnostics. If outbound WhatsApp echoes update inbound activity, operators can misread an outbound-only send as proof that WhatsApp inbound handling is fresh and healthy.
Suspected area
This looks related to WhatsApp Web messages.upsert activity accounting versus outbound echo filtering. The status activity update should line up with accepted inbound-message handling, not raw WhatsApp Web events that later get discarded as echoes, stale history, failed enrichment, or duplicates.
Additional notes
- This was reproduced with real WhatsApp Web, not only unit tests.
- Phone numbers and JIDs are redacted.
- I did not test multi-account WhatsApp or long-lived multi-day behavior.
Summary
When OpenClaw sends a WhatsApp message from the Gateway to the linked account's own WhatsApp number,
openclaw channels status --jsoncan report that WhatsApp inbound activity also advanced.This makes
channels status --probe/ status JSON look like a real inbound WhatsApp message was handled even though the Gateway only performed an outbound send and the logs show no inbound message handling.Environment
95a1c91531defaultReproduction
BEFORE="$(OPENCLAW_HIDE_BANNER=1 openclaw channels status --json)"lastInboundAtandlastOutboundAtfields before/after.Expected behavior
For a Gateway-originated WhatsApp self-send:
lastOutboundAtshould advance.lastInboundAtshould not advance unless a real inbound WhatsApp message is accepted and handled.Actual behavior
Both timestamps advanced for a single Gateway-originated self-send:
{ "marker": "OpenClaw WhatsApp inbound-status echo repro 20260507T174110Z", "sendMessageId": "3EB03B031C04B624AAEA9B", "before": { "lastInboundAt": "2026-05-07T17:18:40.619Z", "lastOutboundAt": "2026-05-07T17:18:40.517Z" }, "after": { "lastInboundAt": "2026-05-07T17:41:18.191Z", "lastOutboundAt": "2026-05-07T17:41:18.145Z" }, "inboundAdvanced": true, "outboundAdvanced": true }The matching redacted Gateway logs showed only outbound send activity for the marker window:
No
Inbound message,web-inbound, orweb-auto-replylog line appeared for the marker.Why this matters
openclaw channels status --probeand the status JSON are used as live channel-health and activity diagnostics. If outbound WhatsApp echoes update inbound activity, operators can misread an outbound-only send as proof that WhatsApp inbound handling is fresh and healthy.Suspected area
This looks related to WhatsApp Web
messages.upsertactivity accounting versus outbound echo filtering. The status activity update should line up with accepted inbound-message handling, not raw WhatsApp Web events that later get discarded as echoes, stale history, failed enrichment, or duplicates.Additional notes