Summary
When using chatStream() with assistant.threads.setStatus(), the streamed content is not visible to users in real-time. Instead, users see the loading indicator until the stream completes, then all content appears at once.
Environment
@slack/bolt: 4.5.0
@slack/web-api: 7.11.0
Platform: Slack Desktop App (macOS) / Slack Web
Workspace type: [Free]
Expected Behavior
Based on this comment :
"the loading indicator should be replaced with the received text for the recipient once the first part of the message is received"
Users should see:
Initial loading status ("Processing...")
First chunk appears immediately after chatStream() is created
Status updates show progress ("Step 1 of 3")
Additional chunks appear as they're appended
Real-time streaming experience
Actual Behavior
CleanShot.2025-10-23.at.18.38.36.mp4
Users see:
Loading indicator the entire time (no matter how long does it take to stop the stream, tried 5mins as well)
Content only appears when stream.stop() is called
All chunks appear at once
No real-time streaming visible
Minimal Reproduction
#!/usr/bin/env bun
import { WebClient } from "@slack/web-api" ;
const client = new WebClient ( process . env . SLACK_BOT_TOKEN ) ;
const CHANNEL = "YOUR_CHANNEL" ;
const USER = "YOUR_USER" ;
async function main ( ) {
// Get team ID
const auth = await client . auth . test ( ) ;
const team = auth . team_id ;
// Create thread
const userMsg = await client . chat . postMessage ( {
channel : CHANNEL ,
text : "Testing streaming" ,
} ) ;
const thread = userMsg . ts ;
// Set initial status
await client . assistant . threads . setStatus ( {
channel_id : CHANNEL ,
thread_ts : thread ,
status : "Processing..." ,
loading_messages : [ "Analyzing request" ] ,
} ) ;
await sleep ( 2000 ) ;
// Start streaming
const streamer = client . chatStream ( {
channel : CHANNEL ,
thread_ts : thread ,
recipient_team_id : team ,
recipient_user_id : USER ,
markdown_text : "**Starting process...**" ,
} ) ;
await sleep ( 2000 ) ;
// Append chunks with status updates
await client . assistant . threads . setStatus ( {
channel_id : CHANNEL ,
thread_ts : thread ,
status : "Step 1 of 3" ,
} ) ;
await streamer . append ( { markdown_text : "\n\n**Step 1**: First chunk" } ) ;
await sleep ( 3000 ) ;
await client . assistant . threads . setStatus ( {
channel_id : CHANNEL ,
thread_ts : thread ,
status : "Step 2 of 3" ,
} ) ;
await streamer . append ( { markdown_text : "\n\n**Step 2**: Second chunk" } ) ;
await sleep ( 3000 ) ;
await client . assistant . threads . setStatus ( {
channel_id : CHANNEL ,
thread_ts : thread ,
status : "Step 3 of 3" ,
} ) ;
await streamer . append ( { markdown_text : "\n\n**Step 3**: Final chunk" } ) ;
await sleep ( 2000 ) ;
// Stop stream
await streamer . stop ( ) ;
await client . assistant . threads . setStatus ( {
channel_id : CHANNEL ,
thread_ts : thread ,
status : "" ,
} ) ;
}
function sleep ( ms ) {
return new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ;
}
main ( ) . catch ( console . error ) ;
Steps to Test
Run the reproduction script
Watch the Slack thread in real-time
Observe when content becomes visible
Question
Is this the expected behavior?
Should content be visible incrementally as chunks are appended or does Slack buffer streaming content until stream.stop() is called?
Do status updates work alongside streaming?
Reference
Summary
When using
chatStream()withassistant.threads.setStatus(), the streamed content is not visible to users in real-time. Instead, users see the loading indicator until the stream completes, then all content appears at once.Environment
@slack/bolt: 4.5.0@slack/web-api: 7.11.0Expected Behavior
Based on this comment:
Users should see:
chatStream()is createdActual Behavior
CleanShot.2025-10-23.at.18.38.36.mp4
Users see:
stream.stop()is calledMinimal Reproduction
Steps to Test
Question
stream.stop()is called?Reference