#10539: feat(hooks): add blocking capability to message_received hookFeat/message received blocking
stale
Cluster:
Plugin and Hook Enhancements
## Summary
This PR enhances the `message_received` hook to support **blocking incoming messages** before they reach the agent. This enables security plugins to intercept and reject malicious messages (e.g., prompt injection attempts).
**Author:** ClawForge Team
## Changes
### 1. New Result Type (`src/plugins/types.ts`)
- Added `PluginHookMessageReceivedResult` with `block`, `blockReason`, `notifyUser`, `notifyAgent`, `threatLevel`, and `auditMetadata` fields
### 2. Hook Implementation (`src/plugins/hooks.ts`)
- Changed `runMessageReceived` from `runVoidHook` to `runModifyingHook`
- Added result merging logic
### 3. Dispatch Logic (`src/auto-reply/reply/dispatch-from-config.ts`)
- Now awaits hook result instead of fire-and-forget
- Checks for `block: true` and returns early
- Sends `notifyUser` message when blocking
## Backward Compatibility
✅ Fully backward compatible
- Existing void handlers return `undefined` → message allowed
- Only handlers explicitly returning `{ block: true }` cause blocking
- Errors in hooks cause fail-open behavior
## Use Case
Enables security plugins like prompt injection detection:
```typescript
api.on("message_received", async (event) => {
if (isPromptInjection(event.content)) {
return { block: true, notifyUser: "Message blocked." };
}
});
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
- Extends the `message_received` plugin hook so handlers can return a structured result that can block inbound messages.
- Updates the hook runner implementation to execute `message_received` via the modifying-hook path and merge results.
- Updates `dispatchReplyFromConfig` to await `message_received` and short-circuit message processing (optionally notifying the user) when `block: true` is returned.
- Adds the `PluginHookMessageReceivedResult` type and updates the hook handler map signature accordingly.
<h3>Confidence Score: 3/5</h3>
- This PR is close, but has a couple of type-level issues that should be fixed before merging.
- Core behavior changes are localized and appear consistent with the goal (block on hook result), but `runMessageReceived` currently calls `runModifyingHook` with incorrect generic parameters and the new result type is not re-exported from `src/plugins/hooks.ts`, which can break compilation and/or consumer imports.
- src/plugins/hooks.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#18004: feat: Add before_message_dispatch hook for blocking inbound messages
by Andy-Haigh · 2026-02-16
85.5%
#11681: feat(plugins): add cancel support to message_received hook
by PrimeTenet · 2026-02-08
81.9%
#7580: feat: add message:received internal hook with prompt injection
by rodrigoschott · 2026-02-03
76.3%
#6405: feat(security): Add HTTP API security hooks for plugin scanning
by masterfung · 2026-02-01
75.9%
#7545: feat(hooks): add message:received hook for pre-turn automation
by wangtian24 · 2026-02-02
75.9%
#10109: feat(plugins): invoke message_received and message_sent hooks
by nezovskii · 2026-02-06
75.5%
#11597: feat(hooks): implement message:received hook
by gnufoo · 2026-02-08
75.1%
#11778: fix(plugins): enforce monotonic hook deny merges
by coygeek · 2026-02-08
75.0%
#19922: feat(hooks): add message:received and message:sent hook events
by NOVA-Openclaw · 2026-02-18
74.3%
#9906: feat: wire message_sending hook in outbound delivery
by teempai · 2026-02-05
73.2%