Skip to content

Slack: reply threading defaults/overrides are inconsistent (docs say off, monitor defaults all) #20827

@tristanmanchester

Description

@tristanmanchester

Summary

Slack reply threading behavior appears inconsistent across docs/config/runtime, and currently prevents a strict "main-channel only" policy.

What I observed

  • In production, Slack channel replies were posted as thread replies even though we wanted no thread replies.
  • Config keys were unset:
    • channels.slack.replyToMode: <unset>
    • channels.slack.replyToModeByChatType: <unset>
  • Runtime/build: openclaw 2026.2.17

Why this looks like a bug

1) Docs say default is off

docs/channels/slack.md says:

  • channels.slack.replyToMode: off|first|all (default off)

(See lines around 233-236 in current repo docs.)

2) Slack monitor provider defaults to all

In source:

  • src/slack/monitor/provider.ts:120
    • const replyToMode = slackCfg.replyToMode ?? "all";

This appears to conflict with docs and with other code paths that treat fallback as off.

3) Thread-origin messages are forcibly pinned to thread regardless of replyToMode

In source:

  • src/slack/monitor/replies.ts:94
    • const effectiveMode = params.incomingThreadTs ? "all" : params.replyToMode;

So if inbound has thread_ts, outgoing stays threaded even when configured off.

Additional inconsistency

Another source path uses fallback off semantics:

  • src/slack/accounts.ts:114
    • return account.replyToMode ?? "off";

So there are at least two different defaults in the codebase (all vs off) depending on path.

Repro (minimal)

  1. Use Slack channel integration with default Slack config (do not set channels.slack.replyToMode).
  2. Send a top-level message in a channel.
  3. Observe reply behavior:
    • In my case, replies went to thread despite expecting main-channel behavior from docs.

Relevant runtime evidence (sanitized)

  • Session key was channel-scoped (no explicit :thread: suffix):
    • sessionKey=agent:main:slack:channel:c0ac6jw1ugk
  • Reply delivery log:
    • [slack] delivered reply to channel:C0AC6JW1UGK
  • User-visible behavior in Slack: reply appears threaded.

Expected behavior

  1. If docs state default off, runtime should also default to off consistently.
  2. There should be a strict mode to keep replies in main channel (even for thread-origin input), for teams that disallow thread responses.

Actual behavior

  • Effective runtime behavior can be thread-first due to ?? "all" and incomingThreadTs ? "all" override.
  • This makes "no thread replies" difficult/impossible to enforce with current defaults/logic.

Proposed direction

  1. Align defaults across code/docs (off vs all) and keep one canonical behavior.
  2. Add explicit strict mode (example: channels.slack.replyToMode: off + channels.slack.thread.forceMainChannel: true) to prevent thread replies even for thread-origin events.
  3. Clarify docs to distinguish:
    • top-level channel message behavior
    • thread-origin behavior
    • explicit reply tags behavior ([[reply_to_*]])

Possibly related (but not identical)

This report is specifically about default/override semantics and inability to enforce strict non-thread replies.

Environment

  • OpenClaw: 2026.2.17
  • Slack: Socket Mode
  • Host: macOS (crownest)

Metadata

Metadata

Assignees

No one assigned

    Labels

    close:duplicateClosed as duplicatededupe:childDuplicate issue/PR child in dedupe cluster

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions