chenhg5/cc-connect · error
slack: finalize streaming card: %w
Error message
slack: finalize streaming card: %w
What it means
Finalize renders the full final content of a streaming card. When the rendered text exceeds slackUpdateMaxText, chat.update cannot edit the existing message, so Finalize falls back to a fresh postMessage via postFresh. This error wraps a failure of that fallback post — the final content could not be delivered by either path.
Source
Thrown at platform/slack/streaming_card.go:147
c.mu.Lock()
defer c.mu.Unlock()
if c.failed {
return nil
}
rendered := core.MarkdownToSlackMrkdwn(content)
if rendered == "" || rendered == c.lastSent {
return nil
}
// Long reply + card already posted: chat.update would 413 with msg_too_long;
// post a fresh message with the full content instead. This is the in-house
// equivalent of "see full reply below" — the partial streaming card stays
// visible above the new full-content message.
if c.ts != "" && len(rendered) > slackUpdateMaxText {
slog.Debug("slack: streaming card finalize switching to fresh postMessage (payload exceeds chat.update limit)",
"size", len(rendered), "limit", slackUpdateMaxText)
if _, err := c.postFresh(ctx, rendered); err != nil {
c.failed = true
return fmt.Errorf("slack: finalize streaming card: %w", err)
}
c.lastSent = rendered
return nil
}
if err := c.render(ctx, rendered); err != nil {
c.failed = true
return fmt.Errorf("slack: finalize streaming card: %w", err)
}
c.lastSent = rendered
return nil
}
// Failed reports whether the card has entered a terminal failed state.
func (c *slackStreamingCard) Failed() bool {
c.mu.Lock()
defer c.mu.Unlock()
return c.failed
}View on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped inner error from postFresh (channel_not_found, rate_limited, invalid_auth) and fix accordingly
- Re-add the bot to the channel or restore chat:write scope if auth/membership is the cause
- Retry the finalize/turn delivery — the card is marked failed, so a re-send posts a fresh card
- Trim the response before rendering if content routinely exceeds the limit
Example fix
// before
if _, err := c.postFresh(ctx, rendered); err != nil {
c.failed = true
return fmt.Errorf("slack: finalize streaming card: %w", err)
}
// after
if _, err := c.postFresh(ctx, rendered); err != nil {
c.failed = true
slog.Error("slack: streaming card finalize fresh-post failed", "channel", c.channel, "size", len(rendered), "err", err)
return fmt.Errorf("slack: finalize streaming card: %w", err)
} Defensive patterns
Strategy: fallback
Validate before calling
if len(rendered) > slackUpdateMaxText {
// oversize: verify we can still post before dropping the old preview
if _, err := c.client.PostMessageContext(ctx, c.channel, slack.MsgOptionText("", false)); err != nil {
return fmt.Errorf("slack: cannot post fallback: %w", err)
}
} Try / catch
if err := card.Finalize(ctx, fullContent); err != nil {
// send final content as a normal message instead
p.client.PostMessageContext(ctx, channel, slack.MsgOptionText(core.MarkdownToSlackMrkdwn(fullContent), false))
} Prevention
- Anticipate oversize finals: the fresh-post fallback path is expected for long responses
- Ensure chat:write and channel membership so postFresh succeeds
- Cap response length in agent config if Slack limits are routinely hit
- Retry delivery as a plain message if the card finalize fails
When it happens
Trigger: Rendered content length > slackUpdateMaxText AND the fallback postFresh PostMessageContext call fails (channel invalid, bot removed, rate limit, network error, context cancelled).
Common situations: Very long agent responses overflowing the chat.update limit exactly when the bot lost channel access or Slack rate limiting kicked in; token scope revoked mid-session; network blip at end of a long turn.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- slack: send preview: %w
- slack: invalid reply context type %T
- codex app-server line exceeds max size (%d bytes): %w
- %s: send preview: no message ID returned
- %s: StreamRichCardText: invalid preview handle type %T
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/c35166c095a971cb.
Report an issue: GitHub.