chenhg5/cc-connect · error
slack: invalid reply context type %T
Error message
slack: invalid reply context type %T
What it means
CreateStreamingCard implements core.StreamingCardPlatform and asserts the reply context is the Slack-internal replyContext struct. This error is returned when any other type is passed — an internal contract violation between the engine and the Slack adapter, meaning the card would be posted with an unknown destination.
Source
Thrown at platform/slack/streaming_card.go:55
client *slack.Client
channel string
threadTS string
mu sync.Mutex
ts string // empty until the first post
failed bool
lastUpdate time.Time
lastSent string
}
// CreateStreamingCard prepares a lazy streaming card; the Slack message is not
// posted until the first content arrives. Implements core.StreamingCardPlatform
// — when present, the engine routes the whole turn through this card and skips
// the plain streaming preview (mutually exclusive, so no double-post).
func (p *Platform) CreateStreamingCard(ctx context.Context, rctx any) (core.StreamingCard, error) {
rc, ok := rctx.(replyContext)
if !ok {
return nil, fmt.Errorf("slack: invalid reply context type %T", rctx)
}
return &slackStreamingCard{client: p.client, channel: rc.channel, threadTS: rc.timestamp}, nil
}
// postFresh posts a brand-new message — the lazy first post for an unseen
// card, or the "too long for chat.update" overflow path used by Finalize.
// Caller must hold c.mu.
func (c *slackStreamingCard) postFresh(ctx context.Context, rendered string) (string, error) {
opts := []slack.MsgOption{slack.MsgOptionText(rendered, false)}
if c.threadTS != "" {
opts = append(opts, slack.MsgOptionPostMessageParameters(slack.PostMessageParameters{ThreadTimestamp: c.threadTS}))
}
_, ts, err := c.client.PostMessageContext(ctx, c.channel, opts...)
return ts, err
}
// render posts the card on first use, then edits it in place thereafter.
// Caller must hold c.mu.View on GitHub (pinned to 4000b2338a)
Solutions
- Ensure the turn's session belongs to the Slack platform (check config.toml platform binding)
- Recreate the session so the reply context is built by the Slack adapter
- Build core and platform/slack from the same source tree
- In tests, construct the context via p.ReconstructReplyCtx("slack:C...") or replyContext literals
Example fix
// before
card, err := p.CreateStreamingCard(ctx, "slack:C123") // string, not replyContext
// after
rc, _ := p.ReconstructReplyCtx("slack:C123")
card, err := p.CreateStreamingCard(ctx, rc) Defensive patterns
Strategy: type-guard
Validate before calling
rc, ok := rctx.(replyContext)
if !ok { return fmt.Errorf("slack: invalid reply context type %T", rctx) } Type guard
func isSlackReplyCtx(v any) bool { _, ok := v.(replyContext); return ok } Try / catch
card, err := p.CreateStreamingCard(ctx, rctx)
if err != nil {
slog.Warn("slack: streaming card unavailable, using plain preview", "err", err)
return nil // engine falls back to plain streaming
} Prevention
- Keep each session pinned to one platform adapter
- Source reply contexts from the Slack adapter only
- Run engine and adapter integration tests on the same build
- Return nil from CreateStreamingCard paths early on foreign contexts
When it happens
Trigger: The engine invokes CreateStreamingCard with a reply context built by another platform, a nil context, or a test fixture of the wrong type, so the type assertion rctx.(replyContext) fails.
Common situations: Session created under one platform but resumed with the Slack platform after config edits; core/adapter version skew; unit tests passing raw structs instead of replyContext.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- slack: invalid reply context type %T
- slack: invalid preview handle type %T
- %s: StreamRichCardText: invalid preview handle type %T
- slack: finalize streaming card: %w
- cron_expr must be a string
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/839d9ee84c041c03.
Report an issue: GitHub.