-
-
Notifications
You must be signed in to change notification settings - Fork 80.7k
[Bug]: WhatsApp plugin uses single agent:${id}:main lane for all chats — distinct contacts share session/jsonl/context #76263
Copy link
Copy link
Open
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.staleMarked as stale due to inactivityMarked as stale due to inactivity
Description
Metadata
Metadata
Assignees
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.staleMarked as stale due to inactivityMarked as stale due to inactivity
Type
Fields
Priority
None yet
[Bug]: WhatsApp plugin uses single
agent:${id}:mainlane for all chats — distinct contacts share session/jsonl/contextSummary
The WhatsApp plugin does not construct a chat-scoped
sessionKeyfor inbound messages. Every conversation across distinct contacts of the same WhatsApp account is routed into the default laneagent:${agentId}:main, which means every contact shares the samesessionId, the same.jsonl, and the same model context. The Telegram plugin handles this correctly: each chat gets its own scoped lane.The practical effect for SaaS / multi-customer deployments: a model that just answered customer A is replying to customer B with A's history still in its context window. So far we've only seen mild manifestations (cache buildup, ~10% extra cost), but cross-customer leak is one short follow-up question away from happening (e.g. customer B asks "y eso?" / "confirmas?" and the model answers based on what customer A asked).
Affects v2026.4.26 and confirmed unchanged in v2026.4.29 (latest).
Reproduction
Multi-tenant SaaS profile with one WhatsApp account routed to one agent. Two distinct contacts (e.g.
+5491111111111and+5491122222222) message the same account within minutes.~/.openclaw-saas/agents/<agent-id>/sessions/sessions.jsonafter both contacts wrote.agent:<agent-id>:main. ItsdeliveryContext.to(or recentfrom) shows whichever contact wrote last..jsonlfile. Both contacts' turns are interleaved in the same file. The model'scacheReadgrows turn over turn including the previous customer's content.Compare with Telegram: messaging the same agent from two distinct Telegram users yields two separate entries (
agent:<agent-id>:telegram:slash:<chatId1>and:<chatId2>), each with its ownsessionIdand its own.jsonl.Expected behavior
Each WhatsApp chat (per
chat_id/ sender E.164, plus group ID for groups) should resolve to its own scopedsessionKey, similar to:This matches the Telegram plugin pattern and would give per-contact context isolation by default.
Code reference (binary inspection, v2026.4.26)
Telegram does scope by chat:
The default fallback in
dist/session-utils-r05OsxB5.jsbuilds:Searching the WhatsApp plugin (
dist/extensions/whatsapp/) does not show an analogous chat-scoped construction —session.runtime,channel.runtime,reply-resolver.runtime, andoutbound-adapterdo not build asessionKeycontainingchat_id/ E.164 / group ID. Inbound therefore falls through to the default:mainkey.There is also no schema option for it:
dist/zod-schema.providers-whatsapp-*.jsandplugin-sdk/src/config/types.whatsapp.d.tsexpose nolanePerChat/sessionScopeflag.Suggested fix
In the WhatsApp plugin's inbound resolution path (the spot that calls into
core.channel.routing.resolveAgentRoute(...)for incoming messages), construct asessionKeyanalogous to Telegram's, e.g.:Optionally guard behind a config flag (default off) for one or two minor releases to avoid breaking existing deployments that intentionally rely on the single-lane behavior.
Workarounds
For deployments hit by this:
sender_idchange in runtime context and treats the turn as a fresh conversation (defense-in-depth, not a real fix — in-context still wins).sessionIdwheneversender_idchanges is feasible but fragile.Environment
openclawv2026.4.26 (also confirmed unchanged in v2026.4.29 by tarball grep).saaswith multiple agents bound by{ channel: "whatsapp", accountId: "<tenant>" }.Happy to share more snippets from the binary or a sanitized
sessions.jsonif useful.