chenhg5/cc-connect · error
%s: invalid reply context type %T
Error message
%s: invalid reply context type %T
What it means
feishu: invalid reply context type is raised in ReplyCard when the reply context value passed in cannot be asserted to the internal replyContext struct. The feishu adapter requires the opaque reply context produced by its own message-receive path. Passing any other type breaks the adapter's contract.
Source
Thrown at platform/feishu/card.go:24
"fmt"
"log/slog"
"strings"
"github.com/chenhg5/cc-connect/core"
lark "github.com/larksuite/oapi-sdk-go/v3"
larkcore "github.com/larksuite/oapi-sdk-go/v3/core"
larkim "github.com/larksuite/oapi-sdk-go/v3/service/im/v1"
)
func plainText(content string) map[string]any {
return map[string]any{"tag": "plain_text", "content": content}
}
// ReplyCard sends a structured card as a reply to the original message.
func (p *interactivePlatform) ReplyCard(ctx context.Context, rctx any, card *core.Card) error {
rc, ok := rctx.(replyContext)
if !ok {
return fmt.Errorf("%s: invalid reply context type %T", p.tag(), rctx)
}
cardJSON := renderCard(card, rc.sessionKey)
if !p.shouldUseThreadOrReplyAPI(rc) {
if rc.chatID == "" {
return fmt.Errorf("%s: chatID is empty, cannot send card", p.tag())
}
return p.createMessage(ctx, rc.chatID, larkim.MsgTypeInteractive, cardJSON, "send card")
}
return p.replyMessage(ctx, rc, larkim.MsgTypeInteractive, cardJSON)
}
// SendCard sends a structured card as a new message to the chat.
func (p *interactivePlatform) SendCard(ctx context.Context, rctx any, card *core.Card) error {
rc, ok := rctx.(replyContext)
if !ok {
return fmt.Errorf("%s: invalid reply context type %T", p.tag(), rctx)
}View on GitHub (pinned to 4000b2338a)
Solutions
- Only pass reply contexts obtained from the feishu platform's message events
- Don't serialize/reconstruct reply contexts manually across restarts
- Check the platform name to ensure the card is sent via the matching adapter
Example fix
// before err := feishuPlatform.ReplyCard(ctx, genericCtx, card) // wrong type // after replyCtx := msg.ReplyContext() // from the feishu event err := feishuPlatform.ReplyCard(ctx, replyCtx, card)
Defensive patterns
Strategy: type-guard
Type guard
rc, ok := rctx.(replyContext); if !ok { return fmt.Errorf("feishu: invalid reply context type %T", rctx) } Try / catch
if err := p.ReplyCard(ctx, rctx, card); err != nil && strings.Contains(err.Error(), "invalid reply context") {
log.Error("reply context from wrong platform", "type", fmt.Sprintf("%T", rctx))
} Prevention
- Route reply contexts only to the platform that produced them
- Tag reply contexts with the platform name before dispatch
- Rebuild contexts from live events instead of caching across restarts
When it happens
Trigger: ReplyCard (card.go:24) called with a reply context object that is not the feishu replyContext type — e.g. a context from a different platform or a caller-constructed value.
Common situations: Cross-platform handle mixing in multi-platform deployments; a caller caching reply contexts across engine restarts; writing a custom engine integration that constructs its own reply context.
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
- %s: SendFile: invalid reply context type %T
- %s: StreamRichCardText: invalid preview handle type %T
- %s: SendAudio: invalid reply context type %T
- %s: SendVideo: invalid reply context type %T
- app_id/app_secret are required
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/ebe50613dc0229b1.
Report an issue: GitHub.