Skip to content

[Bug]: Slack: reasoning/thinking payloads from Claude models leak through non-streaming delivery paths #84319

Description

@ffluk3

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

Problem

When using Claude Opus 4.6 or 4.7 models served, extended thinking content (e.g. "let me do X", "I need to consider...") appears as visible messages in Slack channels. These should be suppressed — the model's thinking capability should be preserved, but the thinking blocks themselves should never reach the user.

Root Cause

The isReasoning suppression check only exists in the streaming delivery path (deliverWithStreaming in dispatch.ts:614):

if (params.payload.isReasoning === true) {
  return;
}

Three other delivery paths bypass this check entirely:

Path File Why it's hit
deliverNormally() dispatch.ts:544 Streaming disabled, streaming fails/falls back, payload has media or Slack blocks
deliver() callback dispatch.ts:776 Non-streaming mode → goes to deliverFinalizableDraftPreviewdeliverNormally
deliverReplies() replies.ts:47 Exported helper called from deliverNormally and stream fallback
deliverSlackSlashReplies() replies.ts:198 Slash command responses

The core routing layer (route-reply.ts, payloads.ts) correctly suppresses reasoning payloads via shouldSuppressReasoningPayload(), but the Slack extension's internal delivery functions operate after that layer and re-introduce the gap.

Affected Models

While there might be more, the following have been confirmed.

Any provider model that emits thinking content blocks, primarily:

  • Claude Opus 4.7 (thinking levels: off, minimal, low, medium, high, xhigh, adaptive, max)
  • Claude Opus 4.6 (thinking levels: off, minimal, low, medium, high, adaptive)

Both via direct Anthropic API and Amazon Bedrock.

Steps to reproduce

Prerequisites

  • OpenClaw instance connected to a Slack workspace
  • Amazon Bedrock access with Claude Opus 4.6 or 4.7 enabled
  • AWS credentials configured (~/.openclaw/credentials/ or AWS SDK chain)

Thinking is enabled by default (adaptive level for Opus 4.6/4.7), so no explicit reasoning config is needed.

Reproduce via non-streaming path (easiest)

  1. Disable Slack streaming in config:
    channels:
      slack:
        streaming:
          mode: "off"
  2. Send a message to the bot in any Slack channel — e.g. a complex prompt like "Compare the pros and cons of three different database architectures for a high-write workload"
  3. Observe: Thinking content like "Let me analyze each architecture..." appears as a visible Slack message before the actual answer

Reproduce via streaming fallback path

  1. Leave streaming enabled (default partial mode)
  2. Send a message that causes the streaming path to fall back to deliverNormally — any of:
    • A reply payload that contains media (image generation, file attachment)
    • A reply payload with Slack blocks (interactive elements)
    • A Slack API streaming error (transient rate limit, timeout)
  3. Observe: The reasoning payload bypasses the deliverWithStreaming guard and flows through deliverNormallydeliverReplies unfiltered

Reproduce via slash command

  1. Configure a Slack slash command (e.g. /ask)
  2. Run: /ask What are the tradeoffs of microservices vs monolith?
  3. Observe: deliverSlackSlashReplies processes all payloads including isReasoning: true ones

Expected behavior

  • Thinking blocks should be suppressed in all Slack delivery paths
  • Only the final answer text should appear in the channel
  • The 🤔 status reaction (if enabled) may briefly appear to signal thinking is occurring, but no thinking text should be posted

Actual behavior

  • Thinking content appears as a separate visible message in Slack, typically prefixed with "Reasoning:\n_hidden_" or containing raw thinking text like "Let me think about...", "I need to consider...", etc.

OpenClaw version

HEAD

Operating system

Debian

Install method

Docker

Model

amazon-bedrock/claude-opus-4.7

Provider / routing chain

openclaw -> bedrock

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

As far as we know, this is something we only experience within the slack integration.

Additional information

No response

Metadata

Metadata

Assignees

Labels

P1High-priority user-facing bug, regression, or broken workflow.bugSomething isn't workingbug:behaviorIncorrect behavior without a crashclawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

Type

No type

Fields

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