{"record":{"id":"3347024564436688","repo":"chenhg5/cc-connect","slug":"slack-invalid-reply-context-type-t-334702","errorCode":null,"errorMessage":"slack: invalid reply context type %T","messagePattern":"slack: invalid reply context type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/slack/streaming.go","lineNumber":27,"sourceCode":"\t\"github.com/slack-go/slack\"\n)\n\n// slackPreviewHandle points at the in-flight streaming-preview message so\n// UpdateMessage can edit it in place via chat.update.\ntype slackPreviewHandle struct {\n\tchannel   string\n\ttimestamp string\n}\n\n// SendPreviewStart posts the initial streaming-preview message (threaded like a\n// normal reply) and returns a handle for subsequent edits. Implements\n// core.PreviewStarter; together with UpdateMessage it lights up the engine's\n// real-time streaming preview for Slack (the engine throttles the edits, so we\n// stay within chat.update rate limits).\nfunc (p *Platform) SendPreviewStart(ctx context.Context, rctx any, content string) (any, error) {\n\trc, ok := rctx.(replyContext)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"slack: invalid reply context type %T\", rctx)\n\t}\n\topts := []slack.MsgOption{\n\t\tslack.MsgOptionText(core.MarkdownToSlackMrkdwn(content), false),\n\t}\n\tif rc.timestamp != \"\" {\n\t\topts = append(opts, slack.MsgOptionPostMessageParameters(slack.PostMessageParameters{ThreadTimestamp: rc.timestamp}))\n\t}\n\t_, ts, err := p.client.PostMessageContext(ctx, rc.channel, opts...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"slack: send preview: %w\", err)\n\t}\n\treturn &slackPreviewHandle{channel: rc.channel, timestamp: ts}, nil\n}\n\n// UpdateMessage edits the preview message in place. The engine passes the handle\n// returned by SendPreviewStart (not the reply context). Implements\n// core.MessageUpdater.\nfunc (p *Platform) UpdateMessage(ctx context.Context, previewHandle any, content string) error {","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/slack/streaming.go#L9-L45","documentation":"SendPreviewStart implements core.PreviewStarter and expects the reply context argument to be the platform-internal replyContext struct. This error is thrown when the engine passes some other type — an internal contract violation between core and the Slack adapter. It is a defensive type assertion, not a user-input problem.","triggerScenarios":"The engine calls SendPreviewStart with a reply context produced by a different platform adapter, or with a nil/legacy context value, so rctx.(replyContext) fails.","commonSituations":"Mixing sessions across platforms after a config change (session restored under a different platform); core/adapter version skew where the reply context type changed; tests passing the wrong fixture.","solutions":["Check which platform created the session that triggered streaming — it must be the Slack platform","Recreate the session so the reply context is built by the Slack adapter","Ensure core and platform/slack are built from the same source tree (no version skew)","Fix test code to pass p.ReconstructReplyCtx(...) or a replyContext value, not an arbitrary type"],"exampleFix":"// before\np.SendPreviewStart(ctx, map[string]any{\"channel\": \"C123\"}, \"hi\") // wrong type\n// after\nrc, _ := p.ReconstructReplyCtx(\"slack:C123\")\np.SendPreviewStart(ctx, rc, \"hi\")","handlingStrategy":"type-guard","validationCode":"rc, ok := rctx.(replyContext)\nif !ok { return fmt.Errorf(\"slack: invalid reply context type %T\", rctx) }","typeGuard":"func asSlackReplyCtx(v any) (replyContext, bool) { rc, ok := v.(replyContext); return rc, ok }","tryCatchPattern":"handle, err := p.SendPreviewStart(ctx, rctx, content)\nif err != nil {\n    slog.Warn(\"slack: preview start failed\", \"err\", err)\n    return nil // degrade to non-streaming reply\n}","preventionTips":["Bind platform and agent per session; never mix adapters for one session","Obtain reply contexts only via the same platform's ReconstructReplyCtx","Keep core and platform packages on the same commit","In tests, build fixtures with the real replyContext type"],"tags":["slack","type-mismatch","streaming","contract"],"backgroundTag":"type-mismatch","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}