Skip to content

fix(discord): suppress reasoning/thinking block payloads from delivery#24969

Merged
steipete merged 1 commit intoopenclaw:mainfrom
Sid-Qin:fix/discord-reasoning-leak
Feb 24, 2026
Merged

fix(discord): suppress reasoning/thinking block payloads from delivery#24969
steipete merged 1 commit intoopenclaw:mainfrom
Sid-Qin:fix/discord-reasoning-leak

Conversation

@Sid-Qin
Copy link
Contributor

@Sid-Qin Sid-Qin commented Feb 24, 2026

Summary

  • Block payloads (info.kind === "block") contain reasoning/thinking content that should only be visible in the internal web UI
  • When streamMode is "partial", these blocks were delivered to Discord as visible messages, leaking chain-of-thought to end users
  • Add an early return for block payloads in the deliver callback, consistent with the WhatsApp fix and Telegram's existing behavior

Changes

  • src/discord/monitor/message-handler.process.ts — skip deliverDiscordReply for info.kind === "block"

Test plan

  • Set streamMode: "partial" with reasoning enabled, verify reasoning blocks are NOT sent to Discord
  • Verify final responses still appear correctly
  • Verify tool updates still stream normally

Fixes #24532

Made with Cursor

Greptile Summary

This PR adds an early return in the Discord deliver callback to suppress info.kind === "block" payloads, which carry reasoning/thinking content. Without this fix, when streamMode is "partial", block payloads were delivered to Discord as visible messages, leaking chain-of-thought content to end users.

  • Adds a guard clause in the Discord message handler's deliver callback at src/discord/monitor/message-handler.process.ts to skip delivery for block payloads
  • The fix is minimal and correctly placed — it returns early before any delivery logic runs
  • Aligns with the repo's guideline in AGENTS.md that streaming/partial replies should not be sent to external messaging surfaces
  • Note: the PR description claims consistency with "the WhatsApp fix and Telegram's existing behavior," but WhatsApp and Telegram actually do deliver block payloads through their respective pipelines (WhatsApp delivers silently; Telegram uses them for reasoning lane streaming). The Discord fix is still correct — it prevents unintended leakage specific to Discord's delivery path

Confidence Score: 5/5

  • This PR is safe to merge — it adds a minimal, well-scoped guard clause that prevents unintended content leakage.
  • The change is a 4-line early return that suppresses block payloads from Discord delivery. It cannot break existing final or tool delivery paths since those are handled by different info.kind values. The fix addresses a real privacy concern (leaking reasoning/thinking content to end users) with the simplest possible approach.
  • No files require special attention.

Last reviewed commit: f3c1a1d

Context used:

  • Context from dashboard - CLAUDE.md (source)
  • Context from dashboard - AGENTS.md (source)

Block payloads (info.kind === "block") contain reasoning/thinking content
that should only be visible in the internal web UI. When streamMode is
"partial", these blocks were being delivered to Discord as visible
messages, leaking chain-of-thought to end users.

Add an early return for block payloads in the deliver callback,
consistent with the WhatsApp fix and Telegram's existing behavior.

Fixes openclaw#24532

Co-authored-by: Cursor <cursoragent@cursor.com>
@openclaw-barnacle openclaw-barnacle bot added channel: discord Channel integration: discord size: XS labels Feb 24, 2026
Copy link
Contributor

@steipete steipete left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed for correctness and simpler alternatives; this is the best scoped change for the issue.

@steipete steipete merged commit 38da3f4 into openclaw:main Feb 24, 2026
23 of 24 checks passed
sagarsaija pushed a commit to sagarsaija/openclaw that referenced this pull request Feb 24, 2026
openclaw#24969)

Block payloads (info.kind === "block") contain reasoning/thinking content
that should only be visible in the internal web UI. When streamMode is
"partial", these blocks were being delivered to Discord as visible
messages, leaking chain-of-thought to end users.

Add an early return for block payloads in the deliver callback,
consistent with the WhatsApp fix and Telegram's existing behavior.

Fixes openclaw#24532

Co-authored-by: Cursor <cursoragent@cursor.com>
Helmi added a commit to Helmi/openclaw that referenced this pull request Feb 24, 2026
When blockStreaming is enabled, normal replies are delivered via
sendBlockReply (info.kind === 'block'). The previous fix for openclaw#24969
blindly suppressed ALL block payloads, causing normal replies to be
silently dropped when blockStreaming is true.

Fix: only suppress block payloads tagged with isReasoning=true,
which are actual reasoning/thinking blocks that should not leak
to end users.

Fixes regression introduced by 38da3f4.
Helmi added a commit to Helmi/openclaw that referenced this pull request Feb 24, 2026
When blockStreaming is enabled, normal replies are delivered via
sendBlockReply (info.kind === 'block'). The previous fix for openclaw#24969
blindly suppressed ALL block payloads, causing normal replies to be
silently dropped when blockStreaming is true.

Fix: only suppress block payloads tagged with isReasoning=true,
which are actual reasoning/thinking blocks that should not leak
to end users.

Fixes regression introduced by 38da3f4.
Helmi added a commit to Helmi/openclaw that referenced this pull request Feb 24, 2026
When blockStreaming is enabled, normal replies are delivered via
sendBlockReply (info.kind === 'block'). The previous fix for openclaw#24969
blindly suppressed ALL block payloads, causing normal replies to be
silently dropped when blockStreaming is true.

Fix: only suppress block payloads tagged with isReasoning=true,
which are actual reasoning/thinking blocks that should not leak
to end users.

Fixes regression introduced by 38da3f4.
plgs2005 pushed a commit to plgs2005/openclaw that referenced this pull request Feb 24, 2026
openclaw#24969)

Block payloads (info.kind === "block") contain reasoning/thinking content
that should only be visible in the internal web UI. When streamMode is
"partial", these blocks were being delivered to Discord as visible
messages, leaking chain-of-thought to end users.

Add an early return for block payloads in the deliver callback,
consistent with the WhatsApp fix and Telegram's existing behavior.

Fixes openclaw#24532

Co-authored-by: Cursor <cursoragent@cursor.com>
Helmi added a commit to Helmi/openclaw that referenced this pull request Feb 24, 2026
When blockStreaming is enabled, normal replies are delivered via
sendBlockReply (info.kind === 'block'). The previous fix for openclaw#24969
blindly suppressed ALL block payloads, causing normal replies to be
silently dropped when blockStreaming is true.

Fix: only suppress block payloads tagged with isReasoning=true,
which are actual reasoning/thinking blocks that should not leak
to end users.

Fixes regression introduced by 38da3f4.
pewallin added a commit to pewallin/openclaw that referenced this pull request Feb 24, 2026
openclaw#24969 introduced an early return for all `info.kind === "block"`
payloads in the Discord deliver callback, intending to suppress
reasoning/thinking content. However, block payloads are the primary
delivery mechanism when `blockStreaming: true` — this broke all
streamed text responses to Discord.

Use the `isReasoning` flag (added in 7d76c24) instead, which
correctly targets only reasoning content.

Fixes openclaw#25836
pewallin added a commit to pewallin/openclaw that referenced this pull request Feb 24, 2026
openclaw#24969 introduced an early return for all `info.kind === "block"`
payloads in the Discord deliver callback, intending to suppress
reasoning/thinking content. However, block payloads are the primary
delivery mechanism when `blockStreaming: true` — this broke all
streamed text responses to Discord.

Use the `isReasoning` flag (added in 7d76c24) instead, which
correctly targets only reasoning content. Update the corresponding
test to set `isReasoning: true` on the fixture payload.

Fixes openclaw#25836
pewallin added a commit to pewallin/openclaw that referenced this pull request Feb 24, 2026
openclaw#24969 introduced an early return for all `info.kind === "block"`
payloads in the Discord deliver callback, intending to suppress
reasoning/thinking content. However, block payloads are the primary
delivery mechanism when `blockStreaming: true` — this broke all
streamed text responses to Discord.

Use the `isReasoning` flag (added in 7d76c24) instead, which
correctly targets only reasoning content. Update the corresponding
test to set `isReasoning: true` on the fixture payload.

Fixes openclaw#25836
xianfeng92 pushed a commit to xianfeng92/openclaw that referenced this pull request Feb 25, 2026
openclaw#24969)

Block payloads (info.kind === "block") contain reasoning/thinking content
that should only be visible in the internal web UI. When streamMode is
"partial", these blocks were being delivered to Discord as visible
messages, leaking chain-of-thought to end users.

Add an early return for block payloads in the deliver callback,
consistent with the WhatsApp fix and Telegram's existing behavior.

Fixes openclaw#24532

Co-authored-by: Cursor <cursoragent@cursor.com>
(cherry picked from commit 38da3f4)
margulans pushed a commit to margulans/Neiron-AI-assistant that referenced this pull request Feb 25, 2026
openclaw#24969)

Block payloads (info.kind === "block") contain reasoning/thinking content
that should only be visible in the internal web UI. When streamMode is
"partial", these blocks were being delivered to Discord as visible
messages, leaking chain-of-thought to end users.

Add an early return for block payloads in the deliver callback,
consistent with the WhatsApp fix and Telegram's existing behavior.

Fixes openclaw#24532

Co-authored-by: Cursor <cursoragent@cursor.com>
brianleach pushed a commit to brianleach/openclaw that referenced this pull request Feb 26, 2026
openclaw#24969)

Block payloads (info.kind === "block") contain reasoning/thinking content
that should only be visible in the internal web UI. When streamMode is
"partial", these blocks were being delivered to Discord as visible
messages, leaking chain-of-thought to end users.

Add an early return for block payloads in the deliver callback,
consistent with the WhatsApp fix and Telegram's existing behavior.

Fixes openclaw#24532

Co-authored-by: Cursor <cursoragent@cursor.com>
mylukin pushed a commit to mylukin/openclaw that referenced this pull request Feb 26, 2026
openclaw#24969)

Block payloads (info.kind === "block") contain reasoning/thinking content
that should only be visible in the internal web UI. When streamMode is
"partial", these blocks were being delivered to Discord as visible
messages, leaking chain-of-thought to end users.

Add an early return for block payloads in the deliver callback,
consistent with the WhatsApp fix and Telegram's existing behavior.

Fixes openclaw#24532

Co-authored-by: Cursor <cursoragent@cursor.com>
r4jiv007 pushed a commit to r4jiv007/openclaw that referenced this pull request Feb 28, 2026
openclaw#24969)

Block payloads (info.kind === "block") contain reasoning/thinking content
that should only be visible in the internal web UI. When streamMode is
"partial", these blocks were being delivered to Discord as visible
messages, leaking chain-of-thought to end users.

Add an early return for block payloads in the deliver callback,
consistent with the WhatsApp fix and Telegram's existing behavior.

Fixes openclaw#24532

Co-authored-by: Cursor <cursoragent@cursor.com>
Maple778 added a commit to Maple778/openclaw that referenced this pull request Mar 2, 2026
…check / data leak

Pattern from PR openclaw#24969

The revised proposal addresses the validation feedback by ensuring the privacy guard for `info.kind === 'block'` is placed strictly at the top of the function (addressing the flow concern), maintains the original variable declaration order to prevent ReferenceErrors (addressing the side effect concern), and includes a specific unit test for the 'block' scenario (addressing the testing concern). The fix logic explicitly filters out 'block' payloads before any logic related to draft streaming, media handling, or final text processing can execute.
Maple778 added a commit to Maple778/openclaw that referenced this pull request Mar 2, 2026
… / data leak

Pattern from PR openclaw#24969

The fix addresses the critical race condition by placing the 'block' filter check at the very top of the `deliver` function. This ensures that for internal 'block' reasoning chunks, the function returns immediately, preventing any text processing (lines 195-203) and, crucially, preventing the initialization of the streaming state for these payloads (lines 212-216). This ensures that the `streaming` object is not initialized with empty data, and subsequent 'final' payloads will correctly initialize and stream only the final content. The fix also addresses the 'incomplete' validation issue by using `info?.kind !== 'block'`. While the contract likely ensures `info` is present, this defensive approach ensures that if `info` is missing (and the payload is unrelated to internal blocking), the message is still delivered to the user, preventing a 'silent failure' bug. The validation logic at line 205 (`!hasText && !hasMedia`) ensures we do not send empty messages.
Takhoffman added a commit that referenced this pull request Mar 2, 2026
…#31723)

* fix(extensions/feishu/src/reply-dispatcher.ts): missing privacy check / data leak

Pattern from PR #24969

The fix addresses the critical race condition by placing the 'block' filter check at the very top of the `deliver` function. This ensures that for internal 'block' reasoning chunks, the function returns immediately, preventing any text processing (lines 195-203) and, crucially, preventing the initialization of the streaming state for these payloads (lines 212-216). This ensures that the `streaming` object is not initialized with empty data, and subsequent 'final' payloads will correctly initialize and stream only the final content. The fix also addresses the 'incomplete' validation issue by using `info?.kind !== 'block'`. While the contract likely ensures `info` is present, this defensive approach ensures that if `info` is missing (and the payload is unrelated to internal blocking), the message is still delivered to the user, preventing a 'silent failure' bug. The validation logic at line 205 (`!hasText && !hasMedia`) ensures we do not send empty messages.

* Fix indentation: remove extra 4 spaces from deliver function body

The deliver function is inside the createReplyDispatcherWithTyping call,
so it should be indented at 2 levels (8 spaces), not 3 levels (12 spaces).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(feishu): cover block payload suppression in reply dispatcher

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
dawi369 pushed a commit to dawi369/davis that referenced this pull request Mar 3, 2026
…openclaw#31723)

* fix(extensions/feishu/src/reply-dispatcher.ts): missing privacy check / data leak

Pattern from PR openclaw#24969

The fix addresses the critical race condition by placing the 'block' filter check at the very top of the `deliver` function. This ensures that for internal 'block' reasoning chunks, the function returns immediately, preventing any text processing (lines 195-203) and, crucially, preventing the initialization of the streaming state for these payloads (lines 212-216). This ensures that the `streaming` object is not initialized with empty data, and subsequent 'final' payloads will correctly initialize and stream only the final content. The fix also addresses the 'incomplete' validation issue by using `info?.kind !== 'block'`. While the contract likely ensures `info` is present, this defensive approach ensures that if `info` is missing (and the payload is unrelated to internal blocking), the message is still delivered to the user, preventing a 'silent failure' bug. The validation logic at line 205 (`!hasText && !hasMedia`) ensures we do not send empty messages.

* Fix indentation: remove extra 4 spaces from deliver function body

The deliver function is inside the createReplyDispatcherWithTyping call,
so it should be indented at 2 levels (8 spaces), not 3 levels (12 spaces).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(feishu): cover block payload suppression in reply dispatcher

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
OWALabuy pushed a commit to kcinzgg/openclaw that referenced this pull request Mar 4, 2026
…openclaw#31723)

* fix(extensions/feishu/src/reply-dispatcher.ts): missing privacy check / data leak

Pattern from PR openclaw#24969

The fix addresses the critical race condition by placing the 'block' filter check at the very top of the `deliver` function. This ensures that for internal 'block' reasoning chunks, the function returns immediately, preventing any text processing (lines 195-203) and, crucially, preventing the initialization of the streaming state for these payloads (lines 212-216). This ensures that the `streaming` object is not initialized with empty data, and subsequent 'final' payloads will correctly initialize and stream only the final content. The fix also addresses the 'incomplete' validation issue by using `info?.kind !== 'block'`. While the contract likely ensures `info` is present, this defensive approach ensures that if `info` is missing (and the payload is unrelated to internal blocking), the message is still delivered to the user, preventing a 'silent failure' bug. The validation logic at line 205 (`!hasText && !hasMedia`) ensures we do not send empty messages.

* Fix indentation: remove extra 4 spaces from deliver function body

The deliver function is inside the createReplyDispatcherWithTyping call,
so it should be indented at 2 levels (8 spaces), not 3 levels (12 spaces).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(feishu): cover block payload suppression in reply dispatcher

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
openclaw#24969)

Block payloads (info.kind === "block") contain reasoning/thinking content
that should only be visible in the internal web UI. When streamMode is
"partial", these blocks were being delivered to Discord as visible
messages, leaking chain-of-thought to end users.

Add an early return for block payloads in the deliver callback,
consistent with the WhatsApp fix and Telegram's existing behavior.

Fixes openclaw#24532

Co-authored-by: Cursor <cursoragent@cursor.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…openclaw#31723)

* fix(extensions/feishu/src/reply-dispatcher.ts): missing privacy check / data leak

Pattern from PR openclaw#24969

The fix addresses the critical race condition by placing the 'block' filter check at the very top of the `deliver` function. This ensures that for internal 'block' reasoning chunks, the function returns immediately, preventing any text processing (lines 195-203) and, crucially, preventing the initialization of the streaming state for these payloads (lines 212-216). This ensures that the `streaming` object is not initialized with empty data, and subsequent 'final' payloads will correctly initialize and stream only the final content. The fix also addresses the 'incomplete' validation issue by using `info?.kind !== 'block'`. While the contract likely ensures `info` is present, this defensive approach ensures that if `info` is missing (and the payload is unrelated to internal blocking), the message is still delivered to the user, preventing a 'silent failure' bug. The validation logic at line 205 (`!hasText && !hasMedia`) ensures we do not send empty messages.

* Fix indentation: remove extra 4 spaces from deliver function body

The deliver function is inside the createReplyDispatcherWithTyping call,
so it should be indented at 2 levels (8 spaces), not 3 levels (12 spaces).


* test(feishu): cover block payload suppression in reply dispatcher

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Discord - Reasoning Block Still Appears After Final Message on streamMode "partial"

2 participants