openclaw - ✅(Solved) Fix [Bug]: Replies can fail with native Slack streaming enabled (user_not_found during stream finalize) when replying to in channel message from Slack Connect user [1 pull requests, 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#70295Fetched 2026-04-23 07:26:36
View on GitHub
Comments
2
Participants
3
Timeline
18
Reactions
0
Author
Timeline (top)
referenced ×12commented ×2labeled ×2closed ×1

Replies in Slack threads appear to fail for Slack Connect users when native Slack streaming is enabled.

In our case, OpenClaw generated the reply internally, but Slack streaming later failed with:

[slack] slack-stream: failed to stop stream: Error: An API error occurred: user_not_found

Error Message

[slack] slack-stream: failed to stop stream: Error: An API error occurred: user_not_found

Steps to reproduce

Enable Slack native streaming: channels.slack.streaming.mode = "partial" channels.slack.streaming.nativeTransport = true Use OpenClaw in a Slack shared channel / thread involving a Slack Connect user Ask the bot to reply in-thread Check delivery behavior and gateway logs

Expected behavior

The final reply should be delivered reliably in the Slack thread.

If native streaming is not supported for that user/thread, OpenClaw should fall back cleanly to normal message delivery without losing the response.

Actual behavior

The reply is generated internally, but Slack streaming fails during stop/finalize with:

[slack] slack-stream: failed to stop stream: Error: An API error occurred: user_not_found I also observed this related log line during debugging:

[slack] slack-stream: streaming API call failed: Error: An API error occurred: user_not_found, falling back So fallback may exist for streaming start/call failure, but finalize/stop failure still appears to cause unreliable delivery.

OpenClaw version

2026.4.14

Operating system

macOS 26.4.1

Install method

npm

Model

chatgpt 5.4

Provider / routing chain

Slack Connect shared channel/thread → Slack Socket Mode → local OpenClaw Gateway (macOS) → agent/session routing (agentname) → OpenAI Codex gpt-5.4 for response generation → OpenClaw Slack transport → Slack Web API / native Slack text streaming. No additional proxy or external model router in the Slack delivery path.

Additional provider/model setup details

Slack mode: socket mode Slack config: channels.slack.streaming.mode = "partial" channels.slack.streaming.nativeTransport = true channels.slack.replyToMode = "first"

Logs, screenshots, and evidence

Root Cause

Replies in Slack threads appear to fail for Slack Connect users when native Slack streaming is enabled.

In our case, OpenClaw generated the reply internally, but Slack streaming later failed with:

[slack] slack-stream: failed to stop stream: Error: An API error occurred: user_not_found

Fix Action

Fixed

PR fix notes

PR #70370: fix(slack): treat Slack Connect finalize errors as benign in stopSlackStream

Description (problem / solution / changelog)

Summary

  • Problem: When Slack native streaming is enabled and the recipient is a Slack Connect user, chat.stopStream fails with An API error occurred: user_not_found. OpenClaw logs slack-stream: failed to stop stream: ... via runtime.error in dispatch, which makes every Slack Connect reply look like an error even though the text delivered via chat.appendStream is already visible to the user.
  • Why it matters: On any workspace that uses Slack Connect / shared channels, native streaming silently looks broken at the dispatch layer. Operators see a stream of red in the gateway log that is caused by the Slack Connect recipient shape, not a dropped reply.
  • What changed: stopSlackStream in extensions/slack/src/streaming.ts now catches session.streamer.stop(...) errors. When the Slack error code is one of user_not_found, team_not_found, or missing_recipient_user_id (all Slack Connect / recipient-resolution cases), swallow the error, keep the session marked as stopped, and log through the existing logVerbose path explaining that appended text is still visible. Any other Slack error still propagates so the caller's existing runtime.error(...) log is preserved.
  • What did NOT change (scope boundary): No behavior change for DMs in the host workspace, thread replies to non-Connect users, or non-streaming delivery paths. The dispatch call site in extensions/slack/src/monitor/message-handler/dispatch.ts is unchanged; this PR stays inside the streaming.ts boundary. No other plugin, core, or SDK 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 #70295
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: stopSlackStream in extensions/slack/src/streaming.ts awaited session.streamer.stop(...) without any error handling. The Slack Connect recipient_user_id / team_id path is not resolvable at finalize time, so Slack returns user_not_found (or sibling codes) on chat.stopStream. The error bubbled up through the outer try/catch in dispatch.ts and was logged via runtime.error as if the reply itself had failed.
  • Missing detection / guardrail: no classification of finalize errors that are "visible text already delivered" vs "stream actually failed". The caller cannot distinguish the two.
  • Contributing context (if known): the issue triage (@rafiki270 on #70295) identified extensions/slack/src/streaming.ts stopSlackStream() as the missing-error-handling site and the finalize failure mode as Slack-Connect-specific.

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/slack/src/streaming.test.ts (new)
  • Scenario the test should lock in: session.streamer.stop() throwing each of the three benign Slack Connect error shapes -> stopSlackStream resolves without throwing and marks the session stopped. An unexpected Slack error code (not_authed) AND a non-Slack-shaped error (new Error("socket reset")) still re-throw so the caller's log path stays intact. Duplicate-stop on an already-stopped session remains a no-op.
  • Why this is the smallest reliable guardrail: stopSlackStream is the seam; the dispatch call site is unchanged.
  • Existing test that already covers this (if any): none - streaming.ts had no direct unit coverage.
  • If no new test is added, why not: N/A (added).

User-visible / Behavior Changes

  • Slack Connect replies with native streaming enabled no longer surface a runtime.error("slack-stream: failed to stop stream: user_not_found") line when the stream text was actually delivered.
  • Log output shifts these finalize failures to logVerbose with a clear note that appended text remains visible and the stream is treated as stopped.

Diagram (if applicable)

N/A

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No (we do not issue follow-on calls on finalize failure; the append() call's text is already at Slack).
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: macOS 15
  • Runtime/container: Node 22, pnpm
  • Model/provider: any (reply is generated upstream; this is the delivery path)
  • Integration/channel (if any): Slack, native streaming enabled
  • Relevant config (redacted):
    channels.slack.streaming.mode = "partial"
    channels.slack.streaming.nativeTransport = true
    channels.slack.replyToMode = "first"

Steps

  1. Configure OpenClaw Slack with native streaming as above.
  2. Trigger a reply in a shared channel/thread that includes a Slack Connect user.

Expected

Reply appears in thread (as it already does via append()) and no slack-stream: failed to stop stream error line appears at the dispatch layer for the user_not_found / team_not_found / missing_recipient_user_id cases.

Actual (before this PR)

[slack] slack-stream: failed to stop stream: Error: An API error occurred: user_not_found at runtime.error level, even when the reply text is visible.

Evidence

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

Local checks before push:

  • pnpm test extensions/slack/src/streaming.test.ts: 1 file, 6 tests pass.
  • pnpm test extensions/slack: 90 files, 736 tests pass.
  • pnpm check:changed --staged (pre-commit): extension lane ran 89 files, 734 tests, all pass.
  • pnpm format:check, pnpm lint on touched files: clean.

Human Verification (required)

  • Verified scenarios (via unit tests mocking ChatStreamer.stop):
    • user_not_found throw -> stopSlackStream resolves, session marked stopped.
    • team_not_found throw -> same.
    • missing_recipient_user_id throw -> same.
    • Unexpected Slack code (not_authed) -> re-thrown with the original message; session still marked stopped to prevent retry loops.
    • Non-Slack error (socket reset) -> re-thrown unchanged.
    • Duplicate stop on an already-stopped session -> no-op, streamer.stop not called.
    • Full Slack extension lane still green (736 tests).
  • Edge cases checked: preserving session.stopped = true on both throw paths so a retry would not re-enter streamer.stop. The error classification reads from err.data.error (shape used by @slack/web-api errors) with a message-string fallback for custom Error subclasses.
  • What I did not verify: I do not have a live Slack Connect workspace to reproduce against. The classification is based on the error strings reported in #70295 and the Slack API docs. If Slack adds / renames finalize error codes for Connect in the future the allowlist needs to follow.

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.

Compatibility / Migration

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

Risks and Mitigations

  • Risk: The allowlist of benign finalize codes hides a real delivery failure if Slack later reuses one of these codes for a case where appended text did NOT reach the user.
    • Mitigation: the three allowlisted codes are recipient-resolution failures that occur at finalize time. chat.appendStream uses the same recipient context, so a user_not_found at stop generally means start/append also hit the same validation path and either already failed (caller sees that as a throw) or succeeded (text is visible). If Slack changes the semantics, the allowlist is a single file and easy to adjust.
  • Risk: Non-streaming delivery is accidentally affected.
    • Mitigation: the change is scoped to stopSlackStream inside extensions/slack/src/streaming.ts. Non-streaming delivery paths do not call it.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • extensions/slack/src/monitor/message-handler/dispatch.preview-fallback.test.ts (modified, +111/-9)
  • extensions/slack/src/monitor/message-handler/dispatch.ts (modified, +86/-4)
  • extensions/slack/src/streaming.test.ts (added, +267/-0)
  • extensions/slack/src/streaming.ts (modified, +162/-7)

Code Example

[slack] slack-stream: failed to stop stream: Error: An API error occurred: user_not_found

### Steps to reproduce

Enable Slack native streaming:
channels.slack.streaming.mode = "partial"
channels.slack.streaming.nativeTransport = true
Use OpenClaw in a Slack shared channel / thread involving a Slack Connect user
Ask the bot to reply in-thread
Check delivery behavior and gateway logs

### Expected behavior

The final reply should be delivered reliably in the Slack thread.

If native streaming is not supported for that user/thread, OpenClaw should fall back cleanly to normal message delivery without losing the response.

### Actual behavior

The reply is generated internally, but Slack streaming fails during stop/finalize with:

[slack] slack-stream: failed to stop stream: Error: An API error occurred: user_not_found
I also observed this related log line during debugging:

[slack] slack-stream: streaming API call failed: Error: An API error occurred: user_not_found, falling back
So fallback may exist for streaming start/call failure, but finalize/stop failure still appears to cause unreliable delivery.

### OpenClaw version

2026.4.14

### Operating system

macOS 26.4.1

### Install method

npm

### Model

chatgpt 5.4

### Provider / routing chain

Slack Connect shared channel/thread → Slack Socket Mode → local OpenClaw Gateway (macOS) → agent/session routing (agentname)OpenAI Codex gpt-5.4 for response generation → OpenClaw Slack transport → Slack Web API / native Slack text streaming. No additional proxy or external model router in the Slack delivery path.

### Additional provider/model setup details

Slack mode: socket mode
Slack config:
channels.slack.streaming.mode = "partial"
channels.slack.streaming.nativeTransport = true
channels.slack.replyToMode = "first"



### Logs, screenshots, and evidence
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

Replies in Slack threads appear to fail for Slack Connect users when native Slack streaming is enabled.

In our case, OpenClaw generated the reply internally, but Slack streaming later failed with:

[slack] slack-stream: failed to stop stream: Error: An API error occurred: user_not_found

### Steps to reproduce

Enable Slack native streaming:
channels.slack.streaming.mode = "partial"
channels.slack.streaming.nativeTransport = true
Use OpenClaw in a Slack shared channel / thread involving a Slack Connect user
Ask the bot to reply in-thread
Check delivery behavior and gateway logs

### Expected behavior

The final reply should be delivered reliably in the Slack thread.

If native streaming is not supported for that user/thread, OpenClaw should fall back cleanly to normal message delivery without losing the response.

### Actual behavior

The reply is generated internally, but Slack streaming fails during stop/finalize with:

[slack] slack-stream: failed to stop stream: Error: An API error occurred: user_not_found
I also observed this related log line during debugging:

[slack] slack-stream: streaming API call failed: Error: An API error occurred: user_not_found, falling back
So fallback may exist for streaming start/call failure, but finalize/stop failure still appears to cause unreliable delivery.

### OpenClaw version

2026.4.14

### Operating system

macOS 26.4.1

### Install method

npm

### Model

chatgpt 5.4

### Provider / routing chain

Slack Connect shared channel/thread → Slack Socket Mode → local OpenClaw Gateway (macOS) → agent/session routing (agentname) → OpenAI Codex gpt-5.4 for response generation → OpenClaw Slack transport → Slack Web API / native Slack text streaming. No additional proxy or external model router in the Slack delivery path.

### Additional provider/model setup details

Slack mode: socket mode
Slack config:
channels.slack.streaming.mode = "partial"
channels.slack.streaming.nativeTransport = true
channels.slack.replyToMode = "first"



### Logs, screenshots, and evidence

```shell

Impact and severity

No response

Additional information

This looks like a Slack Connect-specific issue in native Slack streaming.

My current hypothesis is that streaming is using message.user / recipient_user_id in a way that does not work for Slack Connect users, causing stream lifecycle calls to fail with user_not_found.

extent analysis

TL;DR

Disable native Slack streaming or modify the streaming configuration to handle Slack Connect users correctly.

Guidance

  • Verify that the issue is specific to Slack Connect users and native Slack streaming by testing with non-Connect users and disabling native streaming.
  • Check the Slack API documentation to ensure that the message.user and recipient_user_id fields are being used correctly for Slack Connect users.
  • Consider modifying the OpenClaw configuration to use a different streaming mode or to fall back to normal message delivery when native streaming fails.
  • Test the fallback behavior to ensure that it works correctly and reliably delivers replies in Slack threads.

Example

No code snippet is provided as the issue does not contain sufficient information to create a specific example.

Notes

The issue appears to be specific to Slack Connect users and native Slack streaming, and the root cause is likely related to the use of message.user and recipient_user_id fields in the streaming API calls. However, without further information or documentation, it is difficult to provide a more specific solution.

Recommendation

Apply a workaround by disabling native Slack streaming or modifying the streaming configuration to handle Slack Connect users correctly, as this is likely to be a more feasible solution than waiting for a fix or upgrade.

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

The final reply should be delivered reliably in the Slack thread.

If native streaming is not supported for that user/thread, OpenClaw should fall back cleanly to normal message delivery without losing the response.

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]: Replies can fail with native Slack streaming enabled (user_not_found during stream finalize) when replying to in channel message from Slack Connect user [1 pull requests, 2 comments, 3 participants]