openclaw - 💡(How to fix) Fix [Bug]: Slack typing indicator + status reactions silently disabled under messages.groupChat.visibleReplies: "message_tool" (v2026.4.29) [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#75877Fetched 2026-05-02 05:28:35
View on GitHub
Comments
2
Participants
3
Timeline
3
Reactions
2
Author
Timeline (top)
commented ×2closed ×1

Under messages.groupChat.visibleReplies: "message_tool" (the default for group/channel rooms in v2026.4.27+), the Slack channel handler structurally disables:

  • Slack assistant thread status (setSlackThreadStatus({status: "is typing..."}))
  • The channels.slack.typingReaction emoji (e.g. :hourglass_flowing_sand:)
  • Live preview / native streaming
  • Status reactions (messages.statusReactions)

This contradicts the documentation at docs/channels/group-messages.md line 84:

Typing indicators in groups follow agents.defaults.typingMode. When visible replies use the default message-tool-only mode, typing starts immediately by default so group members can see the agent is working even if no automatic final reply is posted. Explicit typing-mode config still wins.

The user-facing effect: under the recommended/default tool-only mode, group members get no in-flight feedback that the agent is working — no typing indicator, no reaction, no preview. The reply just appears (or doesn't) some seconds later. This is a meaningful UX regression for teams that relied on the typing indicator on prior versions.

Root Cause

In extensions/slack/src/monitor/message-handler/dispatch.ts (v2026.4.29):

// Line 302
const sourceRepliesAreToolOnly = sourceReplyDeliveryMode === "message_tool_only";

// Line 308-309 — status reactions disabled
const statusReactionsEnabled =
  !sourceRepliesAreToolOnly && ...;

// Line 383 — typing controller wired only when NOT tool-only
typing: sourceRepliesAreToolOnly
  ? undefined
  : {
      start: async () => {
        await ctx.setSlackThreadStatus({ ..., status: "is typing..." });
        if (typingReaction && message.ts) {
          await reactSlackMessage(message.channel, message.ts, typingReaction, { ... });
        }
      },
      stop: async () => { ... },
      ...
    },

// Line 448-449 — preview streaming disabled
const previewStreamingEnabled =
  !sourceRepliesAreToolOnly && ...;

// Line 455-456 — streaming disabled
const streamingEnabled =
  !sourceRepliesAreToolOnly && ...;

When sourceRepliesAreToolOnly is true (i.e. tool-only delivery mode), the typing controller is passed as undefined to the reply pipeline — so neither setSlackThreadStatus nor reactSlackMessage(typingReaction) is ever invoked. Same gating disables status reactions, preview streaming, and native streaming.

This appears to be deliberate (the gate is consistent across four call sites) but contradicts what the docs promise. Either:

  • (a) The docs are wrong: typing/status reactions/streaming are intentionally suppressed in tool-only mode and the docs should reflect that, OR
  • (b) The implementation is wrong: the typing controller (at minimum) should still be wired in tool-only mode, since the docs explicitly call out "no automatic final reply is posted" as a reason typing matters MORE in tool-only mode, not less.

(b) seems clearly correct. Tool-only mode is exactly when typing/reaction feedback is most needed, because the user has even less to tell them whether the agent is processing.

Fix Action

Fix / Workaround

In extensions/slack/src/monitor/message-handler/dispatch.ts (v2026.4.29):

Workarounds

For deployments where typing feedback is critical, the only workaround is to flip back to messages.groupChat.visibleReplies: "automatic" and revert any tool-only-specific prompt rewrites. This works but loses the cleaner "silence = no message tool call" semantics that the new default was designed to provide.

Code Example

// Line 302
const sourceRepliesAreToolOnly = sourceReplyDeliveryMode === "message_tool_only";

// Line 308-309 — status reactions disabled
const statusReactionsEnabled =
  !sourceRepliesAreToolOnly && ...;

// Line 383 — typing controller wired only when NOT tool-only
typing: sourceRepliesAreToolOnly
  ? undefined
  : {
      start: async () => {
        await ctx.setSlackThreadStatus({ ..., status: "is typing..." });
        if (typingReaction && message.ts) {
          await reactSlackMessage(message.channel, message.ts, typingReaction, { ... });
        }
      },
      stop: async () => { ... },
      ...
    },

// Line 448-449 — preview streaming disabled
const previewStreamingEnabled =
  !sourceRepliesAreToolOnly && ...;

// Line 455-456 — streaming disabled
const streamingEnabled =
  !sourceRepliesAreToolOnly && ...;

---

typing: {
  start: async () => {
    await ctx.setSlackThreadStatus({ ..., status: "is typing..." });
    if (typingReaction && message.ts) {
      await reactSlackMessage(message.channel, message.ts, typingReaction, { ... }).catch(() => {});
    }
  },
  stop: async () => { ... },
  ...
},
RAW_BUFFERClick to expand / collapse

Summary

Under messages.groupChat.visibleReplies: "message_tool" (the default for group/channel rooms in v2026.4.27+), the Slack channel handler structurally disables:

  • Slack assistant thread status (setSlackThreadStatus({status: "is typing..."}))
  • The channels.slack.typingReaction emoji (e.g. :hourglass_flowing_sand:)
  • Live preview / native streaming
  • Status reactions (messages.statusReactions)

This contradicts the documentation at docs/channels/group-messages.md line 84:

Typing indicators in groups follow agents.defaults.typingMode. When visible replies use the default message-tool-only mode, typing starts immediately by default so group members can see the agent is working even if no automatic final reply is posted. Explicit typing-mode config still wins.

The user-facing effect: under the recommended/default tool-only mode, group members get no in-flight feedback that the agent is working — no typing indicator, no reaction, no preview. The reply just appears (or doesn't) some seconds later. This is a meaningful UX regression for teams that relied on the typing indicator on prior versions.

Reproduction

  1. Set messages.groupChat.visibleReplies: "message_tool" (or rely on the v2026.4.27+ default).
  2. Set agents.defaults.typingMode: "instant" and channels.slack.typingReaction: "hourglass_flowing_sand".
  3. Ensure the bot has assistant:write, reactions:read, and reactions:write scopes.
  4. @mention the bot in a Slack channel where requireMention: true.

Expected: Slack assistant thread status "is typing..." appears immediately; the inbound message gets the :hourglass_flowing_sand: reaction added; both clear when the run finishes.

Actual: No typing indicator. No reaction added. The reply lands when the model finishes, with no in-flight feedback. Logs show no errors (the typing call paths simply aren't invoked).

Root cause

In extensions/slack/src/monitor/message-handler/dispatch.ts (v2026.4.29):

// Line 302
const sourceRepliesAreToolOnly = sourceReplyDeliveryMode === "message_tool_only";

// Line 308-309 — status reactions disabled
const statusReactionsEnabled =
  !sourceRepliesAreToolOnly && ...;

// Line 383 — typing controller wired only when NOT tool-only
typing: sourceRepliesAreToolOnly
  ? undefined
  : {
      start: async () => {
        await ctx.setSlackThreadStatus({ ..., status: "is typing..." });
        if (typingReaction && message.ts) {
          await reactSlackMessage(message.channel, message.ts, typingReaction, { ... });
        }
      },
      stop: async () => { ... },
      ...
    },

// Line 448-449 — preview streaming disabled
const previewStreamingEnabled =
  !sourceRepliesAreToolOnly && ...;

// Line 455-456 — streaming disabled
const streamingEnabled =
  !sourceRepliesAreToolOnly && ...;

When sourceRepliesAreToolOnly is true (i.e. tool-only delivery mode), the typing controller is passed as undefined to the reply pipeline — so neither setSlackThreadStatus nor reactSlackMessage(typingReaction) is ever invoked. Same gating disables status reactions, preview streaming, and native streaming.

This appears to be deliberate (the gate is consistent across four call sites) but contradicts what the docs promise. Either:

  • (a) The docs are wrong: typing/status reactions/streaming are intentionally suppressed in tool-only mode and the docs should reflect that, OR
  • (b) The implementation is wrong: the typing controller (at minimum) should still be wired in tool-only mode, since the docs explicitly call out "no automatic final reply is posted" as a reason typing matters MORE in tool-only mode, not less.

(b) seems clearly correct. Tool-only mode is exactly when typing/reaction feedback is most needed, because the user has even less to tell them whether the agent is processing.

Suggested fix

Decouple the typing controller (and typingReaction) from sourceRepliesAreToolOnly. The typingMode config (instant/message/thinking/never) is the user-controllable knob for "when should the typing signal fire," and instant already exists for the case where there's no streamed text. Tool-only delivery should keep typing.start wired:

typing: {
  start: async () => {
    await ctx.setSlackThreadStatus({ ..., status: "is typing..." });
    if (typingReaction && message.ts) {
      await reactSlackMessage(message.channel, message.ts, typingReaction, { ... }).catch(() => {});
    }
  },
  stop: async () => { ... },
  ...
},

Status reactions and streaming may have separate reasons to remain gated — but typing/typingReaction should not.

Environment

  • OpenClaw v2026.4.29
  • Slack mode: socket
  • agents.defaults.typingMode: "instant"
  • channels.slack.typingReaction: "hourglass_flowing_sand"
  • channels.slack.replyToMode: "all"
  • Bot scopes include assistant:write, reactions:read, reactions:write
  • Model: openai-codex/gpt-5.5 (Codex OAuth)
  • macOS host (Mac Mini M4)

Workarounds

For deployments where typing feedback is critical, the only workaround is to flip back to messages.groupChat.visibleReplies: "automatic" and revert any tool-only-specific prompt rewrites. This works but loses the cleaner "silence = no message tool call" semantics that the new default was designed to provide.

extent analysis

TL;DR

Decouple the typing controller from the sourceRepliesAreToolOnly flag to enable typing indicators in tool-only mode.

Guidance

  • Review the dispatch.ts file and update the typing controller to be independent of the sourceRepliesAreToolOnly flag.
  • Verify that the typingMode config is set to "instant" and channels.slack.typingReaction is set to a valid reaction.
  • Test the changes by setting messages.groupChat.visibleReplies to "message_tool" and checking for typing indicators.
  • Consider updating the documentation to reflect the corrected behavior.

Example

typing: {
  start: async () => {
    await ctx.setSlackThreadStatus({ ..., status: "is typing..." });
    if (typingReaction && message.ts) {
      await reactSlackMessage(message.channel, message.ts, typingReaction, { ... }).catch(() => {});
    }
  },
  stop: async () => { ... },
  ...
},

Notes

The suggested fix only addresses the typing indicator issue and may not resolve other related problems, such as status reactions and streaming.

Recommendation

Apply the suggested fix to decouple the typing controller from the sourceRepliesAreToolOnly flag, as it aligns with the expected behavior described in the documentation.

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…

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 - 💡(How to fix) Fix [Bug]: Slack typing indicator + status reactions silently disabled under messages.groupChat.visibleReplies: "message_tool" (v2026.4.29) [2 comments, 3 participants]