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

  1. Only pass reply contexts obtained from the feishu platform's message events
  2. Don't serialize/reconstruct reply contexts manually across restarts
  3. 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

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


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/ebe50613dc0229b1. Report an issue: GitHub.