chenhg5/cc-connect · error

line: invalid reply context type %T

Error message

line: invalid reply context type %T

What it means

Platform.Reply expects the reply context passed by the engine to be the platform-internal replyContext type; if the assertion rctx.(replyContext) fails, this error reports the actual dynamic type. This is a defensive check against callers supplying a reply context that did not originate from this LINE platform instance (e.g. from a different platform adapter or a stale/custom value).

Source

Thrown at platform/line/line.go:257

	}
}

func (p *Platform) downloadContent(messageID string) ([]byte, error) {
	url := fmt.Sprintf("https://api-data.line.me/v2/bot/message/%s/content", messageID)
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("Authorization", "Bearer "+p.channelToken)
	resp, err := core.HTTPClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	return io.ReadAll(resp.Body)
}

func (p *Platform) Reply(ctx context.Context, rctx any, content string) error {
	rc, ok := rctx.(replyContext)
	if !ok {
		return fmt.Errorf("line: invalid reply context type %T", rctx)
	}

	if content == "" {
		return nil
	}

	content = core.StripMarkdown(content)

	// LINE text message limit is 5000 characters
	messages := splitMessage(content, 5000)
	for _, text := range messages {
		_, err := p.bot.PushMessage(
			&messaging_api.PushMessageRequest{
				To: rc.targetID,
				Messages: []messaging_api.MessageInterface{
					messaging_api.TextMessage{
						Text: text,
					},

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Only pass reply contexts obtained from this LINE platform's incoming webhook events to Reply.
  2. Fix routing logic that stores/shares reply contexts across different platform adapters.
  3. In tests, construct the platform's own replyContext type rather than an arbitrary stub.
  4. If bridging platforms, convert the foreign context into a LINE reply token before calling Reply.

Example fix

// before
p.Reply(ctx, someOtherPlatformCtx, "hello")
// after
rc := line.NewReplyContext(replyTokenFromWebhookEvent)
p.Reply(ctx, rc, "hello")
Defensive patterns

Strategy: type-guard

Type guard

// Go: check the reply context type before use
if rc, ok := rctx.(line.ReplyContext); !ok {
    return fmt.Errorf("not a line reply context: %T", rctx)
} else if rc.ReplyToken == "" {
    return errors.New("line: empty reply token")
}

Try / catch

// Go: caller-side handling
if err := platform.Reply(ctx, rctx, content); err != nil {
    if strings.Contains(err.Error(), "invalid reply context type") {
        slog.Error("reply context came from a different platform; dropping reply", "type", fmt.Sprintf("%T", rctx))
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Calling Reply with a context value produced by another platform's adapter, a hand-constructed value of a different type, or a replyContext captured from a different line.Platform instance/older version whose struct layout differs.

Common situations: Mixing reply contexts across platforms when routing messages through multiple adapters; custom engine code caching reply contexts of the wrong concrete type; tests passing a stub instead of the platform's replyContext.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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