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
- Create hook dir
~/.openclaw/hooks/test-message-sending/ with HOOK.md specifying events: ["message_sending"] and handler.js that writes to /tmp/test.log.
- Run
openclaw hooks list — shows ✓ ready for the hook.
- Restart gateway (
openclaw gateway restart).
- Send a message via webchat, agent replies.
- Check
/tmp/test.log — file is empty, handler was never invoked.
- 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
Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
User-defined hooks (from
hooks/directory) that register for themessage_sendingevent never fire, even thoughopenclaw hooks listshows them asready. Themessage_sendingevent is dispatched viahookRunner.runModifyingHook()(plugin registry only) but lacks a correspondingtriggerInternalHook()call. In contrast,message_sentcorrectly calls both paths.Steps to reproduce
~/.openclaw/hooks/test-message-sending/withHOOK.mdspecifyingevents: ["message_sending"]andhandler.jsthat writes to/tmp/test.log.openclaw hooks list— shows✓ readyfor the hook.openclaw gateway restart)./tmp/test.log— file is empty, handler was never invoked.Expected behavior
User-defined hooks registering
message_sendingshould fire before each outgoing message is delivered to the channel, matching the behavior that plugin hooks receive viahookRunner.runMessageSending(). Themessage_sentevent already bridges both registries (plugin + internal), somessage_sendingshould follow the same pattern.Actual behavior
Hook handler is never called. The
message_sendingevent exists inpluginHookNameSet(deliver-BWpM4stS.js line ~156) andrunMessageSending()is called at line ~1136, but only throughhookRunner(plugin registry). There is notriggerInternalHook(createInternalHookEvent("message", "sending", ...))call anywhere near themessage_sendingdispatch, unlikemessage_sentat 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_sendingeventSeverity: 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, themessage_sendingdispatch (line ~1136) calls onlyhookRunner.runMessageSending()but does NOT calltriggerInternalHook(). Themessage_sentdispatch (line ~1121) correctly calls bothhookRunner.runMessageSent()ANDtriggerInternalHook(createInternalHookEvent("message", "sent", ...)). The missingtriggerInternalHookbridge formessage_sendingmeans user-defined hooks (registered viaregisterInternalHook) are invisible to this event.\n\nSuggested fix: AddtriggerInternalHook(createInternalHookEvent("message", "sending", ...))near line 1136, mirroring themessage_sentpattern.\n\nRelated issues: #24618, #20246, #35889, #13004, #30784