chenhg5/cc-connect · error

max: unexpected replyCtx type %T

Error message

max: unexpected replyCtx type %T

What it means

SendImage implements core.ImageSender and expects replyCtx to be the platform's internal replyContext type (obtained from messages handled by this platform). Passing any other value returns this type-mismatch error.

Source

Thrown at platform/max/max.go:420

	for _, row := range buttons {
		maxRow := make([]maxButton, 0, len(row))
		for _, btn := range row {
			maxRow = append(maxRow, maxButton{
				Type:    "callback",
				Text:    btn.Text,
				Payload: btn.Data,
			})
		}
		maxButtons = append(maxButtons, maxRow)
	}
	return p.sendText(ctx, replyCtx, content, maxButtons)
}

// SendImage implements core.ImageSender.
func (p *Platform) SendImage(ctx context.Context, replyCtx any, img core.ImageAttachment) error {
	rctx, ok := replyCtx.(replyContext)
	if !ok {
		return fmt.Errorf("max: unexpected replyCtx type %T", replyCtx)
	}
	token, err := p.uploadAttachment(ctx, "image", img.Data, img.FileName)
	if err != nil {
		return fmt.Errorf("max: upload image: %w", err)
	}
	body := &maxSendBody{
		Attachments: []maxOutAttachment{{
			Type:    "image",
			Payload: maxTokenPayload{Token: token},
		}},
	}
	return p.postMessage(ctx, rctx.chatID, body)
}

// SendFile implements core.FileSender. MAX routes images uploaded via the file
// endpoint as type="file" in the message, so we honor the declared kind: if the
// mime says image/*, we upload as image so the recipient sees a proper image
// preview instead of a generic file card.

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Only pass the replyCtx that this MAX platform itself handed to your handler.
  2. Verify replyCtx is max's replyContext via a type assertion before calling SendImage.
  3. Ensure session storage serializes/deserializes the context without changing its type.

Example fix

// before
p.SendImage(ctx, someOtherPlatformCtx, img)
// after
if _, ok := someCtx.(replyContext); ok { p.SendImage(ctx, someCtx, img) }
Defensive patterns

Strategy: type-guard

Validate before calling

if _, ok := replyCtx.(replyContext); !ok { return errors.New("replyCtx is not a max replyContext") }

Type guard

func isMaxReplyCtx(v any) bool { _, ok := v.(replyContext); return ok }

Try / catch

if err := p.SendImage(ctx, replyCtx, img); err != nil {
    if strings.Contains(err.Error(), "unexpected replyCtx type") {
        // wrong adapter's context: route to the correct platform
    }
}

Prevention

When it happens

Trigger: Calling SendImage with a replyCtx produced by a different platform, a manually constructed value, or a stale/generic reply context (e.g. nil or a string).

Common situations: Routing reply contexts across platform adapters in a multi-platform setup; persisting replyCtx in a session store and reloading it as the wrong type.

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/09e71c7df2f49add. Report an issue: GitHub.