Bug type
Existing bug
Beta release blocker
No
Summary
On a WhatsApp account linked to OpenClaw as a secondary device, the gateway force-reconnects the WhatsApp socket every 30 minutes even though the socket is healthy. I noticed it since openclaw@2026.4.9 but may have existed prior.
Steps to reproduce
- Link WhatsApp to OpenClaw as a secondary device via WhatsApp standard QR flow (primary phone remains the main WhatsApp client)
- Leave the socket with no inbound traffic for 30+ minutes
- Watch the gateway event log
Expected behaviour
Quiet socket stays up.
Actual behaviour
After ~30 minutes of inbound silence, the gateway marks the WhatsApp channel stale and force-reconnects. Cycle repeats every 30 minutes. The log fills with disconnected (499) -> reconnect pairs.
OpenClaw version
2026.4.22
Logs, screenshots, and evidence
Narrowing it down ended at this line in dist/server.impl-*.js (line 6529 on 4.22 for me):
const DEFAULT_CHANNEL_STALE_EVENT_THRESHOLD_MS = 30 * 6e4;
The health monitor uses inbound-event freshness as its metric. On a quiet device the socket is actually fine, but the threshold still trips and schedules a restart.
The Telegram status adapter opts out of this check via skipStaleSocketHealthCheck: true. The WhatsApp status adapter doesn't set it, so the default 30-minute window applies.
Raising DEFAULT_CHANNEL_STALE_EVENT_THRESHOLD_MS locally to 24h silences the reconnects for me, which is what I've been doing since openclaw@2026.4.9 via a small patch.
Impact and severity
Affected: Secondary WhatsApp setups where the primary phone handles inbound traffic. Doesn't look like it'd hit single-device setups.
Severity: Minor - reconnect churn, no message loss.
Frequency: Every 30 minutes on a quiet socket.
Consequence: 48 reconnects per day in the gateway log; I mistook it for instability initially.
Additional information
PR #69833 in 2026.4.22 added skipStaleSocketHealthCheck: true for Slack via the shared status adapter path. WhatsApp wasn't in that batch.
PR #47513 (closed as superseded) looks like it was going to add this opt-out for WhatsApp.
There's also a separate 30-minute watchdog in the Baileys login path (messageTimeoutMs ?? 1800 * 1e3) that fires for the same reason.
Bug type
Existing bug
Beta release blocker
No
Summary
On a WhatsApp account linked to OpenClaw as a secondary device, the gateway force-reconnects the WhatsApp socket every 30 minutes even though the socket is healthy. I noticed it since
openclaw@2026.4.9but may have existed prior.Steps to reproduce
Expected behaviour
Quiet socket stays up.
Actual behaviour
After ~30 minutes of inbound silence, the gateway marks the WhatsApp channel stale and force-reconnects. Cycle repeats every 30 minutes. The log fills with
disconnected (499)-> reconnect pairs.OpenClaw version
2026.4.22
Logs, screenshots, and evidence
Narrowing it down ended at this line in
dist/server.impl-*.js(line 6529 on 4.22 for me):The health monitor uses inbound-event freshness as its metric. On a quiet device the socket is actually fine, but the threshold still trips and schedules a restart.
The Telegram status adapter opts out of this check via
skipStaleSocketHealthCheck: true. The WhatsApp status adapter doesn't set it, so the default 30-minute window applies.Raising
DEFAULT_CHANNEL_STALE_EVENT_THRESHOLD_MSlocally to 24h silences the reconnects for me, which is what I've been doing sinceopenclaw@2026.4.9via a small patch.Impact and severity
Affected: Secondary WhatsApp setups where the primary phone handles inbound traffic. Doesn't look like it'd hit single-device setups.
Severity: Minor - reconnect churn, no message loss.
Frequency: Every 30 minutes on a quiet socket.
Consequence: 48 reconnects per day in the gateway log; I mistook it for instability initially.
Additional information
PR #69833 in 2026.4.22 added
skipStaleSocketHealthCheck: truefor Slack via the shared status adapter path. WhatsApp wasn't in that batch.PR #47513 (closed as superseded) looks like it was going to add this opt-out for WhatsApp.
There's also a separate 30-minute watchdog in the Baileys login path (
messageTimeoutMs ?? 1800 * 1e3) that fires for the same reason.