chenhg5/cc-connect · error

qqbot: unknown message type %q

Error message

qqbot: unknown message type %q

What it means

SendImage() switches on rctx.messageType, which can only be "group" or "c2c" for a well-formed reply context; anything else hits the default branch and returns this error. It signals an internally inconsistent or corrupted reply context rather than a caller-visible input problem.

Source

Thrown at platform/qqbot/qqbot.go:253

func (p *Platform) SendImage(ctx context.Context, replyCtx any, img core.ImageAttachment) error {
	rctx, ok := replyCtx.(*replyContext)
	if !ok {
		return fmt.Errorf("qqbot: SendImage: invalid reply context type %T", replyCtx)
	}

	fileInfo, err := p.uploadRichMedia(rctx, 1, img.Data, "")
	if err != nil {
		return fmt.Errorf("qqbot: upload image: %w", err)
	}

	var url string
	switch rctx.messageType {
	case "group":
		url = fmt.Sprintf("%s/v2/groups/%s/messages", p.apiBase(), rctx.groupOpenID)
	case "c2c":
		url = fmt.Sprintf("%s/v2/users/%s/messages", p.apiBase(), rctx.userOpenID)
	default:
		return fmt.Errorf("qqbot: unknown message type %q", rctx.messageType)
	}

	body := map[string]any{
		"msg_type": 7,
		"media":    map[string]any{"file_info": fileInfo},
	}
	if rctx.eventMsgID != "" {
		body["msg_id"] = rctx.eventMsgID
		body["msg_seq"] = p.nextMsgSeq(rctx.eventMsgID)
	}

	return p.apiRequest("POST", url, body)
}

// uploadRichMedia uploads a file to QQ Bot rich media API and returns the file_info.
// fileType: 1=image, 2=video, 3=audio, 4=file.
func (p *Platform) uploadRichMedia(rctx *replyContext, fileType int, data []byte, fileName string) (string, error) {
	var url string

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Upgrade the qqbot package to a version that supports the message type in your context.
  2. Check where the *replyContext was created — it should only come from the platform's own receive path.
  3. Log the full reply context (groupOpenID/userOpenID/messageType) to identify how it was corrupted.
  4. Handle channel-type messages via a different code path if the platform does not map them to group/c2c sends.

Example fix

// before
// replyContext built by hand:
rctx := &replyContext{messageType: "guild", groupOpenID: id}
err := p.SendImage(ctx, rctx, img) // unknown message type "guild"
// after
rctx := msg.ReplyContext() // platform-issued, messageType is "group" or "c2c"
err := p.SendImage(ctx, rctx, img)
Defensive patterns

Strategy: validation

Validate before calling

if rc.messageType != "group" && rc.messageType != "c2c" {
    return fmt.Errorf("unsupported messageType %q for image send", rc.messageType)
}

Type guard

func sendableReplyContext(rc *replyContext) bool {
    return rc.messageType == "group" || rc.messageType == "c2c"
}

Try / catch

if err := p.SendImage(ctx, replyCtx, img); err != nil {
    if strings.Contains(err.Error(), "unknown message type") {
        // upgrade adapter or route channel-type messages elsewhere
    }
}

Prevention

When it happens

Trigger: A *replyContext whose messageType field was set to an unexpected value (future message types like channel/guild not yet handled, or a manually constructed context).

Common situations: Upgrading the library after QQ added new message types while running an older adapter that never learned the new type string; hand-crafted contexts in tests; concurrency bugs that overwrite messageType.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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