Skip to content

fix(whatsapp): guard updateLastRoute when dmScope isolates DM sessions#24949

Merged
steipete merged 3 commits into
openclaw:mainfrom
kevinWangSheng:fix/whatsapp-dm-last-route
Feb 24, 2026
Merged

fix(whatsapp): guard updateLastRoute when dmScope isolates DM sessions#24949
steipete merged 3 commits into
openclaw:mainfrom
kevinWangSheng:fix/whatsapp-dm-last-route

Conversation

@kevinWangSheng

@kevinWangSheng kevinWangSheng commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

Problem

When session.dmScope is set to "per-channel-peer", WhatsApp DMs correctly resolve isolated session keys, but updateLastRouteInBackground unconditionally wrote lastTo to the main session key. This caused:

  1. Reply routing corruption: Every WhatsApp DM sender overwrites the main session's lastTo — subsequent auto-replies route to whoever messaged last
  2. Privacy violation: Agent replies intended for User A get delivered to User B if User B messaged more recently
  3. Heartbeat/cron misrouting: Heartbeats using channel: "last" resolve against the corrupted main session

Root Cause

In src/web/auto-reply/monitor/process-message.ts, updateLastRouteInBackground always wrote to params.route.mainSessionKey regardless of whether the DM was isolated.

Fix

Only update main session's lastRoute when the DM session actually IS the main session (sessionKey === mainSessionKey):

// Only update main session's lastRoute when DM actually IS the main session.
// When dmScope="per-channel-peer", the DM uses an isolated sessionKey,
// and updating mainSessionKey would corrupt routing for the session owner.
if (dmRouteTarget && params.route.sessionKey === params.route.mainSessionKey) {
  updateLastRouteInBackground({ ... });
}

Testing

  • pnpm build passes
  • pnpm tsgo passes
  • pnpm lint passes

Behavior

  • When dmScope="main" (default): sessionKey === mainSessionKeyupdateLastRoute fires as before. No behavior change.
  • When dmScope="per-channel-peer": sessionKey !== mainSessionKeyupdateLastRoute is skipped, preventing main session corruption.

Fixes #24912

Greptile Summary

Prevented WhatsApp DM routing corruption when session.dmScope="per-channel-peer" by guarding updateLastRouteInBackground to only update the main session's lastRoute when the DM session actually IS the main session.

  • Fixed critical bug where isolated DM sessions (sessionKey !== mainSessionKey) were overwriting the main session's lastRoute, causing replies to route to whoever messaged last instead of the intended recipient
  • Added condition params.route.sessionKey === params.route.mainSessionKey to guard the update (line 330 in src/web/auto-reply/monitor/process-message.ts:330)
  • Maintains backward compatibility: when dmScope="main" (default), sessionKey === mainSessionKey so behavior is unchanged
  • PR also includes PR_STATUS.md tracking file for agent workflow coordination (non-functional change)

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The fix is surgical and correct: it adds a single condition to prevent corrupting the main session's lastRoute when DM sessions are isolated. The logic is sound - when dmScope="per-channel-peer", isolated DM sessions have different sessionKey values from mainSessionKey, and updating the main session with isolated DM routing data breaks reply routing. The guard preserves existing behavior for default dmScope="main" since those keys are equal. All CI checks passed.
  • No files require special attention

Last reviewed commit: 7296045

shenghui kevin and others added 3 commits February 24, 2026 03:54
When session.dmScope is set to 'per-channel-peer', WhatsApp DMs correctly
resolve isolated session keys, but updateLastRouteInBackground unconditionally
wrote lastTo to the main session key. This caused reply routing corruption
and privacy violations.

Only update main session's lastRoute when the DM session actually IS
the main session (sessionKey === mainSessionKey).

Fixes openclaw#24912
@steipete
steipete force-pushed the fix/whatsapp-dm-last-route branch from 7296045 to 5d79c90 Compare February 24, 2026 03:55
@steipete
steipete merged commit ebde897 into openclaw:main Feb 24, 2026
@steipete

Copy link
Copy Markdown
Contributor

Landed via temp rebase onto main.

  • Gate: deferred full gate across batch at end (per maintainer request)
  • Land commit: 5d79c90
  • Merge commit: ebde897

Thanks @kevinWangSheng!

margulans pushed a commit to margulans/Neiron-AI-assistant that referenced this pull request Feb 25, 2026
kevinWangSheng pushed a commit to kevinWangSheng/openclaw that referenced this pull request Feb 26, 2026
kevinWangSheng pushed a commit to kevinWangSheng/openclaw that referenced this pull request Feb 26, 2026
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 1, 2026
…@kevinWangSheng)

(cherry picked from commit ebde897)

# Conflicts:
#	CHANGELOG.md
#	src/web/auto-reply/monitor/process-message.inbound-contract.test.ts
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 3, 2026
…@kevinWangSheng)

(cherry picked from commit ebde897)

# Conflicts:
#	CHANGELOG.md
#	src/web/auto-reply/monitor/process-message.inbound-contract.test.ts
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: whatsapp-web Channel integration: whatsapp-web size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: WhatsApp DM updateLastRoute overwrites mainSessionKey regardless of dmScope

2 participants