openclaw - ✅(Solved) Fix [Bug]: message_sending hook event not firing for user-defined hooks [1 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#73542Fetched 2026-04-29 06:18:30
View on GitHub
Comments
2
Participants
3
Timeline
5
Reactions
0
Timeline (top)
commented ×2labeled ×2cross-referenced ×1

User-defined hooks (from hooks/ directory) that register for the message_sending event never fire, even though openclaw hooks list shows them as ready. The message_sending event is dispatched via hookRunner.runModifyingHook() (plugin registry only) but lacks a corresponding triggerInternalHook() call. In contrast, message_sent correctly calls both paths.

Root Cause

Root cause: In deliver-BWpM4stS.js, the message_sending dispatch (line ~1136) calls only hookRunner.runMessageSending() but does NOT call triggerInternalHook(). The message_sent dispatch (line ~1121) correctly calls both hookRunner.runMessageSent() AND triggerInternalHook(createInternalHookEvent("message", "sent", ...)). The missing triggerInternalHook bridge for message_sending means user-defined hooks (registered via registerInternalHook) are invisible to this event.\n\nSuggested fix: Add triggerInternalHook(createInternalHookEvent("message", "sending", ...)) near line 1136, mirroring the message_sent pattern.\n\nRelated issues: #24618, #20246, #35889, #13004, #30784

Fix Action

Fix / Workaround

User-defined hooks (from hooks/ directory) that register for the message_sending event never fire, even though openclaw hooks list shows them as ready. The message_sending event is dispatched via hookRunner.runModifyingHook() (plugin registry only) but lacks a corresponding triggerInternalHook() call. In contrast, message_sent correctly calls both paths.

Hook handler is never called. The message_sending event exists in pluginHookNameSet (deliver-BWpM4stS.js line ~156) and runMessageSending() is called at line ~1136, but only through hookRunner (plugin registry). There is no triggerInternalHook(createInternalHookEvent("message", "sending", ...)) call anywhere near the message_sending dispatch, unlike message_sent at line ~1121 which correctly bridges both.

Affected: All users who create user-defined hooks with message_sending event Severity: High — prevents pre-delivery message guardrails for user hooks Frequency: Always (100% reproducible) Consequence: Cannot implement output filtering, content validation, or message cancellation via user hooks. Only workaround is writing a full plugin.

PR fix notes

PR #73570: fix(hooks): bridge message_sending event to internal hook registry

Description (problem / solution / changelog)

Root Cause

The message_sending event was dispatched only through the plugin hook runner (hookRunner.runMessageSending()) but was never bridged to the internal hook registry via triggerInternalHook(). This meant user-defined hooks (registered in ~/.openclaw/hooks/) listening for message_sending were never invoked.

In contrast, message_sent correctly calls both paths: the plugin hook runner AND triggerInternalHook(createInternalHookEvent("message", "sent", ...)).

Fix

Add a triggerInternalHook(createInternalHookEvent("message", "sending", ...)) call in deliverOutboundPayloads, immediately after applyMessageSendingHook() returns, mirroring the existing message_sent pattern.

The internal hook is fire-and-forget (notification only) since triggerInternalHook returns Promise<void> — content modification still goes through the plugin hook runner path. User-defined hooks will now receive the event notification as expected.

Verification

  • Single file change, 22 lines added
  • Mirrors the proven message_sent bridging pattern at line ~667
  • CI will validate via existing hook dispatch tests

Fixes #73542

Changed files

  • src/infra/outbound/deliver.ts (modified, +22/-0)
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

User-defined hooks (from hooks/ directory) that register for the message_sending event never fire, even though openclaw hooks list shows them as ready. The message_sending event is dispatched via hookRunner.runModifyingHook() (plugin registry only) but lacks a corresponding triggerInternalHook() call. In contrast, message_sent correctly calls both paths.

Steps to reproduce

  1. Create hook dir ~/.openclaw/hooks/test-message-sending/ with HOOK.md specifying events: ["message_sending"] and handler.js that writes to /tmp/test.log.
  2. Run openclaw hooks list — shows ✓ ready for the hook.
  3. Restart gateway (openclaw gateway restart).
  4. Send a message via webchat, agent replies.
  5. Check /tmp/test.log — file is empty, handler was never invoked.
  6. Check gateway logs — no errors, no hook invocation logs.

Expected behavior

User-defined hooks registering message_sending should fire before each outgoing message is delivered to the channel, matching the behavior that plugin hooks receive via hookRunner.runMessageSending(). The message_sent event already bridges both registries (plugin + internal), so message_sending should follow the same pattern.

Actual behavior

Hook handler is never called. The message_sending event exists in pluginHookNameSet (deliver-BWpM4stS.js line ~156) and runMessageSending() is called at line ~1136, but only through hookRunner (plugin registry). There is no triggerInternalHook(createInternalHookEvent("message", "sending", ...)) call anywhere near the message_sending dispatch, unlike message_sent at line ~1121 which correctly bridges both.

OpenClaw version

2026.3.24 (cff6dc9)

Operating system

macOS 15.4 (Darwin 24.4.0 arm64)

Install method

mac app (AutoClaw Desktop)

Model

glm-5.1

Provider / routing chain

openclaw -> zhipu/glm-5.1 (direct)

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

Affected: All users who create user-defined hooks with message_sending event Severity: High — prevents pre-delivery message guardrails for user hooks Frequency: Always (100% reproducible) Consequence: Cannot implement output filtering, content validation, or message cancellation via user hooks. Only workaround is writing a full plugin.

Additional information

Root cause: In deliver-BWpM4stS.js, the message_sending dispatch (line ~1136) calls only hookRunner.runMessageSending() but does NOT call triggerInternalHook(). The message_sent dispatch (line ~1121) correctly calls both hookRunner.runMessageSent() AND triggerInternalHook(createInternalHookEvent("message", "sent", ...)). The missing triggerInternalHook bridge for message_sending means user-defined hooks (registered via registerInternalHook) are invisible to this event.\n\nSuggested fix: Add triggerInternalHook(createInternalHookEvent("message", "sending", ...)) near line 1136, mirroring the message_sent pattern.\n\nRelated issues: #24618, #20246, #35889, #13004, #30784

extent analysis

TL;DR

The most likely fix is to add a triggerInternalHook call for the message_sending event in deliver-BWpM4stS.js to bridge the plugin and internal hook registries.

Guidance

  • Verify that the message_sending event is correctly registered in the HOOK.md file and that the handler.js is properly configured to write to /tmp/test.log.
  • Check the deliver-BWpM4stS.js file to confirm that the triggerInternalHook call is missing for the message_sending event, but present for the message_sent event.
  • Consider adding the suggested triggerInternalHook call near line 1136 to mirror the message_sent pattern, allowing user-defined hooks to fire for the message_sending event.
  • Review related issues (#24618, #20246, #35889, #13004, #30784) for potential insights into similar problems and their resolutions.

Example

No code snippet is provided as the issue description already includes the necessary details and suggested fix.

Notes

The provided information suggests a specific root cause and a targeted fix. However, without access to the full codebase or the ability to test changes, the effectiveness of the suggested fix cannot be guaranteed.

Recommendation

Apply the workaround by adding the triggerInternalHook call for the message_sending event, as this directly addresses the identified root cause and is consistent with the existing pattern for the message_sent event.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

User-defined hooks registering message_sending should fire before each outgoing message is delivered to the channel, matching the behavior that plugin hooks receive via hookRunner.runMessageSending(). The message_sent event already bridges both registries (plugin + internal), so message_sending should follow the same pattern.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: message_sending hook event not firing for user-defined hooks [1 pull requests, 2 comments, 3 participants]