OpenClaw’s WhatsApp ACP Binding Bug Is a Sandbox Boundary Problem, Not a Routing Inconvenience
The dangerous OpenClaw bug this morning is not that WhatsApp routing is awkward. Awkward routing is a support ticket. The reported failure in issue #92449 is sharper: a WhatsApp direct message can resolve to the intended agent ID while failing to materialize the configured ACP runtime, which means a conversation expected to run inside a remote ACP/Codex backend can silently execute locally on the gateway host.
That distinction matters. In a modern agent stack, “which agent answered?” is not the real boundary. The real boundary is the runtime envelope: filesystem access, credential scope, process isolation, audit trail, provider profile, approval policy, and whether execution happens in a local embedded runner or a remote ACP harness. If the UI-level route looks correct but the execution backend is wrong, operators get the worst version of safety: confidence without isolation.
The report names OpenClaw 2026.6.5, @openclaw/whatsapp 2026.6.5, WhatsApp direct messages, an acpx ACP backend, and a Linux gateway host. The sanitized configuration is exactly the sort of setup teams are going to use in production: global acp.enabled: true, backend acpx, an agent runtime with type: "acp", and a binding entry with type: "acp", agentId: "sandboxed-agent", channel: "whatsapp", plus account and direct-peer selectors. That is not an exotic edge case. That is the obvious way to expose a sandboxed agent over a chat channel.
The observed session key tells the story. Instead of the configured ACP-shaped key — something like agent:sandboxed-agent:acp:binding:whatsapp:<account>:<hash> — the session stayed in the local channel shape: agent:sandboxed-agent:whatsapp:direct:<peer>. A direct runtime probe reportedly returned resolveConfiguredAcpBindingRecord(...) => null, which suggests the configured binding was never compiled or materialized. The issue suspects the WhatsApp plugin lacks the configured-binding adapter fields exposed by other channel plugins: bindings.compileConfiguredBinding and bindings.matchInboundConversation.
The bug is silent where it should be loud
The most troubling part is not that a binding failed. Bindings fail. Plugins drift. Channel adapters miss parity. The problem is that the failure appears to degrade into local execution rather than failing closed. If a configuration says type: "acp", and the channel cannot compile or match that binding, the platform should reject startup, quarantine the route, or emit a blocking diagnostic before the first user message lands. A sandbox boundary should never become a best-effort hint.
This is not the first time WhatsApp binding behavior has looked security-relevant. The report points to older issue #75211, where WhatsApp bindings in OpenClaw 2026.4.14 were said to be ignored, routing inbound messages to a default agent instead of the configured target. That earlier issue was stale, but the new report narrows the failure class: not ordinary route selection, but ACP binding materialization. The visible agent can be right while the runtime boundary is wrong.
That is an important evolution in agent-platform risk. Early chat-agent failures were mostly about personality and destination: did the message go to the wrong bot? Now routing determines whether a message gets access to local shell tools, a different credential store, a remote controlled harness, a sandboxed filesystem, or a production gateway host. The control plane is no longer decorative. It is part of the security model.
Practitioners should test the runtime, not the label
If you run OpenClaw over WhatsApp, Telegram, Slack, or any other chat front door, do not validate routing by asking “did the right named agent answer?” That is insufficient. Validate the execution envelope. In each channel, run a safe environment-revealing command or diagnostic task, inspect the session key, confirm ACP/Codex artifacts exist where expected, and verify logs show the configured backend. If the agent name is correct but the session key is local, you have not proven isolation.
The same principle applies beyond OpenClaw. Multi-agent products love route maps: this peer goes to sales, that channel goes to support, this group goes to the restricted relay agent. But a route map is policy only if the runtime enforces it. Otherwise it is a nicely formatted wish. Teams should include channel-binding tests in upgrade checks, especially when plugins own part of the binding compilation path. If a channel plugin does not implement configured-binding adapters, the platform should make that visible as an unsupported configuration, not discoverable only through a production incident.
There is also a least-privilege lesson here. A local gateway host often has more ambient authority than a remote ACP sandbox: local files, service credentials, companion app state, channel plugins, and administrative config. If chat-originated work is supposed to be sandboxed remotely, accidental local execution is not a harmless fallback. It may be a privilege escalation from “restricted chat worker” to “whatever the gateway can do.” That is the wrong default in exactly the environment where WhatsApp is attractive: human-friendly access to automation.
The right fix is probably two-layered. First, WhatsApp needs parity with the configured-binding adapter contract if it supports ACP bindings at all. Second, OpenClaw should add a cross-channel invariant: configured ACP bindings must materialize to ACP session identity, or the route is blocked. Logs and doctor checks should say which bindings compiled, which did not, and which channel plugin owns the missing capability. Operators should not need to reverse-engineer session-key shapes to find a sandbox miss.
The editorial take is simple: when chat becomes the control plane, routing bugs become sandbox bugs. OpenClaw should treat them with that severity. A local fallback may be convenient for demos. In production, it is exactly how boundaries disappear.
Sources: OpenClaw issue #92449, OpenClaw issue #75211, OpenClaw subagents docs, OpenClaw automation tasks docs