← NEWS DESK
security advisory

OpenClaw Restores Outbound Safety Hooks on Routed Channel Replies

A merged main-branch fix makes normal routed agent replies pass through plugin rewrite and cancellation hooks before channel delivery.

Independent reporting and tested guidance for OpenClaw operators · Editorial standards

OpenClaw has merged a fix for a channel delivery gap that could let normal routed agent replies bypass plugin rewrites or cancellation. The affected message_sending hook is a safety boundary: a plugin may use it to redact, rewrite or stop content before Telegram, Discord, WhatsApp or another provider makes the reply visible.

The fix is on main, not automatically in every installed package. Operators who depend on outbound policy plugins should identify a containing release and test the real channel path before treating the boundary as restored.

Why this matters

A policy hook that runs on one send path but not another is worse than an obviously unsupported hook. It creates a plausible but false control: direct or durable sends may be filtered while the most common automatic reply route goes straight to the provider callback.

Issue #92374 tracks the wider problem. PR #113448 addresses the normal routed-delivery slice. It does not claim to finish every preview-finalization and terminal-event ownership case in the parent issue.

The new delivery order

For each logical routed payload, the channel turn lifecycle now composes the modifying hooks in this order:

  1. reply_payload_sending;
  2. message_sending; and then
  3. native channel delivery.

A cancellation should stop the provider send. A successful send can then produce the terminal message_sent event through the owning path.

The implementation distinguishes two ownership modes:

  • core-managed or durable delivery, where the shared path owns hook execution and delivery; and
  • provider-owned delivery, used by hybrid Telegram and Discord funnels that perform their own finalization and must invoke the message_sending boundary exactly once.

That split avoids running a modifier twice, but it creates a plugin SDK responsibility. A provider-owned adapter that forgets the hook can recreate the original bypass; an adapter that runs it twice can duplicate rewrites, side effects or cancellation decisions.

Interpretation: delivery ownership is now part of the security contract, not merely an internal callback detail.

What upstream proved

The merged PR reports 294 focused assertions across the shared turn lifecycle, auto-reply dispatch, Discord, Telegram and WhatsApp surfaces, plus the changed-surface gate and a production build.

It also records live cancellation evidence for two routed automatic-reply paths:

Channel Observed hook counts Provider-visible result
Telegram Desktop DM to a real bot reply_payload_sending 1, message_sending 1, message_sent 0 No reply visible after cancellation
Discord guild mention reply_payload_sending 1, message_sending 1, message_sent 0 No matching reply during the 45-second observation window

The published traces contain lengths and one-way hashes rather than credentials or raw private message content. The PR also attributes successful live delivery paths to Telegram, Mattermost and Matrix evidence.

This evidence is useful but scoped. Cancellation proves that the hook can stop a send on the exercised Telegram and Discord paths. It does not independently prove every channel adapter, streaming mode, partial delivery, retry or preview-finalization branch.

Who needs to act

Operators using outbound policy plugins

If a plugin redacts secrets, applies compliance text, rewrites links or blocks certain replies, do not validate it with a direct-send command alone. The acceptance test must begin with real inbound channel traffic and produce a normal agent reply through the configured route.

Use harmless marker content and verify all three outcomes:

  • an unmodified reply is delivered once;
  • a rewrite is visible exactly once; and
  • a cancellation produces no provider-visible reply and no message_sent event.

Run those checks for every enabled channel and every delivery mode you use, including streaming or previews where applicable.

Channel plugin authors

Review the updated inbound delivery contract before adopting the containing SDK. Determine whether your adapter uses shared core delivery or owns message_sending itself.

For a provider-owned funnel, tests should prove:

  1. reply_payload_sending runs once;
  2. message_sending runs once;
  3. cancellation prevents every native send;
  4. suppression does not later flush through a retry or finalizer;
  5. a successful reply is not modified twice;
  6. provider IDs and final content reach message_sent through one owner; and
  7. durable retries do not cross into the provider-owned path unexpectedly.

Do not infer correctness from a green “message delivered” test. The dangerous regression is that delivery succeeds while policy never ran.

Security and compliance owners

Treat the containing upgrade as a control revalidation event. Record which plugin owns each rewrite or cancellation, which transport proves the result, and how failures appear in logs without retaining sensitive message bodies.

If the policy is mandatory, fail closed when the hook framework or plugin is unavailable. A warning after the provider has accepted the message is not enforcement.

What remains open

The merged PR explicitly leaves provider-finalized preview settlement and final message_sent ID/content ownership outside its scope. The canonical issue therefore remains relevant even after this normal route is fixed.

Operators using Telegram or Discord previews, streaming edits, media-bearing replies or custom adapters should not generalize the cancellation proof beyond the exercised path. Follow the parent issue and validate those modes separately.

Evidence and limits

OpenClaw Academy reviewed the official merged PR, the canonical issue relationship, the landed chronology and the redacted live-evidence summary. We did not connect a live bot, install a policy plugin or independently observe provider delivery.

The upstream review history initially flagged missing live proof and the risk of delegating hook ownership to providers. The author subsequently added redacted Telegram and Discord cancellation traces before merge. That resolves the specific proof gap for those paths, not the broader need for each adapter to demonstrate its own ownership contract.

Bottom line

This merge repairs an important false boundary: normal routed replies should no longer skip the hook plugins rely on to rewrite or cancel outbound content.

But the fix also makes ownership explicit. Once a channel adapter owns delivery, it owns the obligation to execute the safety hook exactly once and honor its result. Upgrade when the change reaches your release, then prove the policy through the same inbound-to-provider route your users actually exercise.

THE RECEIPTS

Claims should survive the click.

Primary links used for this article are listed openly. If the evidence changes, the verification date changes with it.
  1. 01Run outbound hooks on routed agent replies — PR #113448
  2. 02Canonical hook-bypass report — issue #92374
  3. 03Unify routed outbound hook ownership — commit 66a75bb

THE OPERATOR BRIEF

One useful email when the signal earns it.

Release impact, security changes and repository intelligence. No daily sludge.