openclaw - ✅(Solved) Fix [Bug]: Signal status reactions do not run when messages.statusReactions.enabled is true [1 pull requests, 1 comments, 2 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#72020Fetched 2026-04-27 05:35:56
View on GitHub
Comments
1
Participants
2
Timeline
3
Reactions
0
Author
Timeline (top)
closed ×1commented ×1cross-referenced ×1

Signal does not emit lifecycle status reactions when messages.statusReactions.enabled is true because the Signal inbound handler never wires the status reaction controller into dispatch callbacks.

Error Message

  • done or error at terminal state

Root Cause

Signal does not emit lifecycle status reactions when messages.statusReactions.enabled is true because the Signal inbound handler never wires the status reaction controller into dispatch callbacks.

Fix Action

Fix / Workaround

Signal does not emit lifecycle status reactions when messages.statusReactions.enabled is true because the Signal inbound handler never wires the status reaction controller into dispatch callbacks.

Signal should update reactions on the inbound message using the shared status reaction lifecycle, similar to other channels that already wire createStatusReactionController into dispatch callbacks:

No automatic lifecycle status reaction is sent for Signal inbound messages. Signal has reaction send helpers, but the inbound monitor never creates a status reaction controller and never passes status callbacks to dispatchInboundMessage.

PR fix notes

PR #72025: fix(signal): enable inbound status reactions

Description (problem / solution / changelog)

Summary

Describe the problem and fix in 2-5 bullets:

  • Problem: Signal has reaction send helpers, but inbound runs never wired messages.statusReactions.enabled into the shared status reaction lifecycle.
  • Why it matters: Signal users get no queued/thinking/tool/compacting/done/error visual feedback during long-running agent turns even when status reactions are configured.
  • What changed: Create a Signal status reaction controller for eligible inbound messages, route lifecycle callbacks through dispatchInboundMessage, and send reactions via sendReactionSignal for direct and group messages.
  • What did NOT change (scope boundary): No config shape changes, no Signal REST/native transport changes, and no agent/tool message-action behavior changes.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #72020
  • Related #20393
  • Related #65919
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: Signal's inbound handler dispatched messages without creating a StatusReactionController or passing lifecycle callbacks (onReplyStart, onToolStart, compaction callbacks, terminal state handling) into dispatchInboundMessage.
  • Missing detection / guardrail: Signal had send-reaction helper tests, but no inbound regression test for messages.statusReactions.enabled.
  • Contributing context (if known): Other channels already wire the shared status reaction controller; Signal had the transport primitive but not the inbound lifecycle wiring.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: extensions/signal/src/monitor/event-handler.status-reactions.test.ts
  • Scenario the test should lock in: Signal direct and group inbound messages with messages.statusReactions.enabled send queued and done reactions through the correct direct recipient or groupId/targetAuthor route.
  • Why this is the smallest reliable guardrail: It exercises the Signal inbound handler, dispatch callback wiring, and Signal reaction transport seam without needing a live Signal daemon.
  • Existing test that already covers this (if any): N/A
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

Signal now honors messages.statusReactions.enabled for inbound runs by updating reactions on the triggering message during the agent lifecycle.

Diagram (if applicable)

Before:
Signal inbound -> dispatchInboundMessage -> no status reaction callbacks -> no lifecycle reactions

After:
Signal inbound -> StatusReactionController -> dispatch lifecycle callbacks -> sendReactionSignal -> queued/done status reactions

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: Linux / Ubuntu 24.04
  • Runtime/container: Node 22 + pnpm checkout
  • Model/provider: N/A for regression test
  • Integration/channel (if any): Signal
  • Relevant config (redacted):
{
  "messages": {
    "ackReaction": "👀",
    "ackReactionScope": "all",
    "statusReactions": {
      "enabled": true
    }
  },
  "channels": {
    "signal": {
      "dmPolicy": "open",
      "allowFrom": ["*"]
    }
  }
}

Steps

  1. Configure Signal with messages.statusReactions.enabled: true.
  2. Send a Signal DM or allowed Signal group message that triggers an agent run.
  3. Observe reactions on the inbound message during processing and completion.

Expected

  • Signal sends lifecycle status reactions such as queued/ack and done (plus intermediate thinking/tool/compacting when those callbacks fire).

Actual

  • Before this fix, Signal sent no automatic lifecycle status reactions because the inbound dispatch path did not wire status reaction callbacks.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Targeted verification:

  • pnpm test extensions/signal/src/monitor/event-handler.status-reactions.test.ts
  • pnpm lint:extensions

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: Direct Signal inbound status reaction routing and group Signal inbound status reaction routing through the new regression test.
  • Edge cases checked: Direct recipient uses sender recipient; group reaction uses empty recipient plus groupId and targetAuthor.
  • What you did not verify: Live Signal daemon/container end-to-end reaction delivery.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: Signal reaction API failures could add noisy logs during long runs.
    • Mitigation: Reaction send failures are caught and logged through existing verbose logging; they do not fail message dispatch.

Changed files

  • extensions/signal/src/monitor/event-handler.status-reactions.test.ts (added, +222/-0)
  • extensions/signal/src/monitor/event-handler.ts (modified, +123/-13)

Code Example

{
     "messages": {
       "ackReaction": "👀",
       "ackReactionScope": "all",
       "statusReactions": {
         "enabled": true
       }
     },
     "channels": {
       "signal": {
         "dmPolicy": "open",
         "allowFrom": ["*"]
       }
     }
   }
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

Signal does not emit lifecycle status reactions when messages.statusReactions.enabled is true because the Signal inbound handler never wires the status reaction controller into dispatch callbacks.

Steps to reproduce

  1. Run OpenClaw from upstream main at ca0232ff0ea12fb74081ab17e5b122fb488d6217 with Signal enabled and a config like:

    {
      "messages": {
        "ackReaction": "👀",
        "ackReactionScope": "all",
        "statusReactions": {
          "enabled": true
        }
      },
      "channels": {
        "signal": {
          "dmPolicy": "open",
          "allowFrom": ["*"]
        }
      }
    }
  2. Send a Signal DM or allowed Signal group message that triggers an agent run.

  3. Observe the inbound message while the agent processes, calls tools, compacts, and finishes.

Expected behavior

Signal should update reactions on the inbound message using the shared status reaction lifecycle, similar to other channels that already wire createStatusReactionController into dispatch callbacks:

  • queued / ack reaction when the run is accepted
  • thinking during model/reasoning work
  • tool/coding/web reaction during tool calls
  • compacting during compaction
  • done or error at terminal state

Actual behavior

No automatic lifecycle status reaction is sent for Signal inbound messages. Signal has reaction send helpers, but the inbound monitor never creates a status reaction controller and never passes status callbacks to dispatchInboundMessage.

Code evidence from upstream main:

  • extensions/signal/src/monitor/event-handler.ts dispatches inbound messages with only disableBlockStreaming and onModelSelected in replyOptions.
  • The same Signal tree has sendReactionSignal / removeReactionSignal helpers in extensions/signal/src/send-reactions.ts, so the transport primitive exists.
  • Signal tests do not cover messages.statusReactions, createStatusReactionController, or lifecycle callbacks.
  • Other channels on main already wire status reactions, for example Telegram, Discord, and Slack use createStatusReactionController / statusReactions.enabled / resolveAckReaction.

OpenClaw version

Upstream main at ca0232ff0ea12fb74081ab17e5b122fb488d6217 (package version in this checkout: 2026.4.25).

Operating system

Linux / Ubuntu 24.04 for code inspection and regression test authoring.

Install method

pnpm dev checkout.

Model

N/A - this is channel lifecycle wiring before/during dispatch, not model-specific.

Provider / routing chain

N/A - this is channel lifecycle wiring before/during dispatch, not provider-specific.

Additional provider/model setup details

N/A.

Logs, screenshots, and evidence

Static evidence from upstream main:

  • Signal dispatch path lacks status reaction callbacks in extensions/signal/src/monitor/event-handler.ts.
  • git grep -E 'statusReactions|createStatusReactionController|resolveAckReaction|shouldAckReaction' main -- extensions/signal/src/monitor/event-handler.ts finds no status reaction wiring.
  • git grep -E 'createStatusReactionController|statusReactions.*enabled|resolveAckReaction' main -- extensions/telegram/src extensions/discord/src extensions/slack/src shows equivalent wiring exists in other channels.

Impact and severity

Affected: Signal users who configure messages.statusReactions.enabled expecting lifecycle reactions.

Severity: Medium UX regression/behavior gap. Signal users get no visual progress signal while other channels can show queued/thinking/tool/done reactions.

Frequency: Always for Signal inbound runs on main, based on the missing wiring in the only Signal inbound dispatch path.

Consequence: Configured Signal status reactions are a no-op; users cannot tell whether a long-running Signal-triggered agent turn is accepted, thinking, using tools, compacting, done, or failed.

Additional information

Related but not identical:

  • #20393 covered Signal instant ack reactions, not the full lifecycle messages.statusReactions.enabled flow.
  • #65919 tracks a broader presence-lifetime concern across channels.

extent analysis

TL;DR

The most likely fix is to wire the status reaction controller into dispatch callbacks for Signal inbound messages.

Guidance

  • Review the extensions/signal/src/monitor/event-handler.ts file and add the necessary code to create a status reaction controller and pass status callbacks to dispatchInboundMessage.
  • Verify that the createStatusReactionController function is called and that the statusReactions.enabled flag is checked before sending lifecycle reactions.
  • Compare the Signal implementation with other channels (e.g., Telegram, Discord, Slack) that already wire status reactions to identify any missing pieces.
  • Test the changes with a Signal DM or group message to ensure that lifecycle reactions are sent correctly.

Example

// extensions/signal/src/monitor/event-handler.ts
const statusReactionController = createStatusReactionController();
const replyOptions = {
  disableBlockStreaming: true,
  onModelSelected: (model) => {
    // ...
  },
  statusCallbacks: statusReactionController.getStatusCallbacks(),
};
dispatchInboundMessage(replyOptions);

Notes

The fix requires modifying the Signal inbound handler to wire the status reaction controller into dispatch callbacks. This change should be tested thoroughly to ensure that lifecycle reactions are sent correctly for Signal messages.

Recommendation

Apply the workaround by modifying the extensions/signal/src/monitor/event-handler.ts file to wire the status reaction controller into dispatch callbacks, as this will fix the issue for Signal users who configure messages.statusReactions.enabled.

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

Signal should update reactions on the inbound message using the shared status reaction lifecycle, similar to other channels that already wire createStatusReactionController into dispatch callbacks:

  • queued / ack reaction when the run is accepted
  • thinking during model/reasoning work
  • tool/coding/web reaction during tool calls
  • compacting during compaction
  • done or error at terminal state

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]: Signal status reactions do not run when messages.statusReactions.enabled is true [1 pull requests, 1 comments, 2 participants]