Skip to content

Slack: a stream segment that Slack expired is left showing "Something went wrong" #1036

Open

Description

@xcscxr

Bug Description

When Slack expires a native stream segment before the adapter stops it, stream() either continues in a new message or returns the expired one, and never edits the expired message. Slack shows a stream it closed itself as a "Something went wrong" pill. The thread keeps an error-looking message even though the reply was delivered.

Code on main (1e7a61e), packages/adapter-slack/src/index.ts:

  • The rotateSegment catch path ("stream segment expired before rotation, continuing in a new message") starts the next segment and leaves the expired one as is.
  • The final stop() catch path ("stream-end blocks skipped" / "delivering the rest in a new message") returns or abandons the expired message without editing it.
  • The only editMessage in stream() belongs to the post-and-edit fallback.

Steps to Reproduce

  1. createSlackAdapter({ agentView: true }) with the default streamSegmentMaxAgeMs.
  2. thread.post(source), where source yields some text, stays silent for 6 minutes (a long tool call), then yields more.
  3. Slack expires the first segment during the gap. On the next delta, rotateSegment's stop() fails with message_not_in_streaming_state, and the reply continues in a new message.
  4. Look at the first message.

Expected Behavior

The expired message keeps the content it already streamed, like a normally stopped segment.

Actual Behavior

The expired message stays as Slack sealed it, and Slack renders that as "Something went wrong". We found this by reading the code. The rendering comes from our direct API test and the reports below, not from a run through the adapter.

Chat SDK Version

4.41.0 (also on main @ 1e7a61e)

Platform Adapter

Slack

Additional Context

Evidence that a sealed, never-stopped stream renders as an error, and that chat.update repairs it:

Suggested fix: in both expired paths, chat.update the expired message (segment.streamer.ts) with the content it already had, close any open task, then continue as today.

Related: #911 (a rotated segment with an in-progress task shows a red error icon; still on main, since rotateSegment's stop() sends no closing task_update), #884, #607.

Activity

  1. n1shanthb commented on Oct 19, 2026

    @n1shanthb

    Hey, I'd like to work on this.

    I checked the current Slack stream() implementation, and both the rotateSegment and final stop() expiration handlers still leave the expired message without attempting a repair.

    I'm thinking of adding a best effort chat.update using only that segment's confirmed text, without changing the existing recovery behavior if the update fails or there's no timestamp to update.

    I'd add regression coverage for both paths, including update failures, missing timestamps and unfinished code fences.

    Should this also preserve task/plan content or would a text-only repair be an acceptable first scope?

    Does this approach sound okay?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions