Skip to content

Workspace hooks registered for message_received never fire (internal vs plugin hook dispatch mismatch) #22790

@kaashifahmad

Description

@kaashifahmad

Bug Description

Workspace hooks (defined in hooks/ directory) that register for the message_received event never fire. The hook handler is registered but the event dispatch goes through a different system.

Steps to Reproduce

  1. Create a workspace hook in hooks/my-hook/handler.js that listens for message_received
  2. Send a message through any channel (e.g., WhatsApp group message)
  3. Observe that the hook handler never executes

Root Cause

There are two separate hook dispatch systems in the codebase:

  1. Internal hook system (registerInternalHook / triggerInternalHook) — used by workspace hooks

    • Workspace hooks register via registerInternalHook at entry.js:1423:
      for (const event of normalizedEvents) registerInternalHook(event, handler);
    • registerInternalHook defined at entry.js:342
  2. Plugin hook runner (runVoidHook) — used by the message delivery pipeline

    • message_received is dispatched via runVoidHook in the deliver modules:
      // deliver-DJ-Cgh2V.js:148
      return runVoidHook("message_received", event, ctx);
    • This pattern is consistent across all deliver variants (deliver-89BlqwHR.js:154, deliver-BWpM4stS.js:149, deliver-Ch7yu2ZU.js:151, deliver-DJ-Cgh2V.js:148)

The runVoidHook function dispatches to plugin typed hooks, not to the internal hook registry. So workspace hooks registered via registerInternalHook for message_received are never called.

Expected Behavior

Workspace hooks registered for message_received should fire when messages are received, just like plugin hooks do.

Suggested Fix

Either:

  • Have runVoidHook("message_received", ...) also call triggerInternalHook("message_received", ...), or
  • Route workspace hook registration through the plugin hook system instead of the internal hook system

Environment

  • OpenClaw version: 2026.2.19-2
  • OS: macOS 26.3 (arm64)
  • Node: v24.13.0

Impact

This makes workspace hooks unusable for message capture/logging use cases. Our specific case: a whatsapp-logger hook meant to write inbound WhatsApp messages to a JSONL file never fires despite being correctly registered.

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleMarked as stale due to inactivity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions