chenhg5/cc-connect · error

wecom-ws: SendFile: invalid reply context type %T

Error message

wecom-ws: SendFile: invalid reply context type %T

What it means

SendFile expects its rctx parameter to be the platform-internal wsReplyContext type produced when the platform delivered an inbound message. Any other value (nil, a context from another platform, or a hand-built value) cannot identify the target chat and is rejected with this type-check error.

Source

Thrown at platform/wecom/websocket_outbound_media.go:162

		return name
	}
	switch strings.ToLower(img.MimeType) {
	case "image/jpeg", "image/jpg":
		return "image.jpg"
	case "image/gif":
		return "image.gif"
	case "image/webp":
		return "image.webp"
	default:
		return "image.png"
	}
}

// SendFile uploads and sends a file through the WeCom AI Bot WebSocket API.
func (p *WSPlatform) SendFile(ctx context.Context, rctx any, file core.FileAttachment) error {
	rc, ok := rctx.(wsReplyContext)
	if !ok {
		return fmt.Errorf("wecom-ws: SendFile: invalid reply context type %T", rctx)
	}
	if rc.chatID == "" {
		return fmt.Errorf("wecom-ws: chatID is empty, cannot send file")
	}
	if len(file.Data) == 0 {
		return fmt.Errorf("wecom-ws: file data is empty")
	}

	mediaID, err := p.uploadWSMedia(ctx, "file", wsFileFileName(file), file.Data)
	if err != nil {
		return fmt.Errorf("wecom-ws: send file: %w", err)
	}
	if err := p.sendWSMediaMessage(ctx, rc.chatID, "file", mediaID); err != nil {
		return fmt.Errorf("wecom-ws: send file: %w", err)
	}
	return nil
}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Always pass the wsReplyContext value that the wecom-ws platform gave you with the inbound message
  2. Do not construct reply contexts manually; obtain them from the engine's message dispatch
  3. Check the %T in the error message to see which concrete type you actually passed
  4. If context must cross layers, keep it as any and pass through unmodified

Example fix

// before
p.SendFile(ctx, ctx, file) // passes context.Context
// after
p.SendFile(ctx, replyCtx, file) // replyCtx is the wsReplyContext from the inbound message
Defensive patterns

Strategy: type-guard

Type guard

rc, ok := rctx.(wsReplyContext)
if !ok {
	return fmt.Errorf("SendFile requires the wecom-ws reply context, got %T", rctx)
}

Try / catch

if err := p.SendFile(ctx, replyCtx, file); err != nil && strings.Contains(err.Error(), "invalid reply context type") {
	log.Error("reply context not from wecom-ws", "gotType", fmt.Sprintf("%T", replyCtx))
}

Prevention

When it happens

Trigger: Calling WSPlatform.SendFile with rctx that is not a wsReplyContext — e.g. passing nil, ctx.Context, or a reply context captured from a different platform adapter.

Common situations: Code reuses a reply context across platforms; a test harness passes a stub; context was serialized/stored and lost its concrete type; engine called SendFile with nil because no inbound message context existed.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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