{"record":{"id":"2303012a10a5e481","repo":"chenhg5/cc-connect","slug":"weixin-s-empty-payload","errorCode":null,"errorMessage":"weixin: %s: empty payload","messagePattern":"weixin: (.+?): empty payload","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/weixin/media_outbound.go","lineNumber":57,"sourceCode":"}\n\nfunc (p *Platform) resolveReplyContext(replyCtx any) (*replyContext, error) {\n\trc, ok := replyCtx.(*replyContext)\n\tif !ok || rc == nil {\n\t\treturn nil, fmt.Errorf(\"weixin: invalid reply context\")\n\t}\n\tif strings.TrimSpace(rc.contextToken) == \"\" {\n\t\trc.contextToken = p.getContextToken(rc.peerUserID)\n\t}\n\tif strings.TrimSpace(rc.contextToken) == \"\" {\n\t\treturn nil, fmt.Errorf(\"weixin: missing context_token for peer %q\", rc.peerUserID)\n\t}\n\treturn rc, nil\n}\n\nfunc (p *Platform) uploadToWeixinCDN(ctx context.Context, to string, plaintext []byte, mediaType int, label string) (*cdnUploadedRef, error) {\n\tif len(plaintext) == 0 {\n\t\treturn nil, fmt.Errorf(\"weixin: %s: empty payload\", label)\n\t}\n\tif strings.TrimSpace(p.cdnBaseURL) == \"\" {\n\t\treturn nil, fmt.Errorf(\"weixin: cdn_base_url is empty\")\n\t}\n\trawSize := len(plaintext)\n\taesKey := make([]byte, 16)\n\tif _, err := rand.Read(aesKey); err != nil {\n\t\treturn nil, fmt.Errorf(\"weixin: %s: aes key: %w\", label, err)\n\t}\n\tfilekey := randomHex(16)\n\treq := getUploadURLRequest{\n\t\tFilekey:     filekey,\n\t\tMediaType:   mediaType,\n\t\tToUserID:    to,\n\t\tRawsize:     rawSize,\n\t\tRawfilemd5:  md5Hex(plaintext),\n\t\tFilesize:    aesECBPaddedSize(rawSize),\n\t\tNoNeedThumb: true,","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/weixin/media_outbound.go#L39-L75","documentation":"uploadToWeixinCDN refuses to upload a zero-length payload, returning an error labeled with the sending operation (SendImage/SendFile/SendAudio). Uploading empty bytes to the WeChat CDN would produce a corrupt/invalid media item.","triggerScenarios":"SendImage with img.Data == nil/empty, SendFile with file.Data empty, or SendAudio where the audio bytes (after any conversion) end up empty.","commonSituations":"Attachment download from the messaging platform returned 0 bytes (failed fetch silently ignored); reading a file that was truncated or a directory; caller passed nil data by mistake.","solutions":["Verify the attachment data is fully downloaded and non-empty before calling Send*.","Check the file on disk has size > 0 (os.Stat) before reading it into memory.","Log/handle upstream fetch errors so a failed download is not passed through as empty bytes."],"exampleFix":"// before\nif err := fetchAttachment(); err != nil { /* ignored */ }\np.SendImage(ctx, rc, core.ImageAttachment{Data: data}) // weixin: SendImage: empty payload\n// after\nif len(data) == 0 { return errors.New(\"attachment download failed\") }\np.SendImage(ctx, rc, core.ImageAttachment{Data: data})","handlingStrategy":"validation","validationCode":"if len(payload) == 0 { return errors.New(\"refusing to send empty media payload\") }","typeGuard":null,"tryCatchPattern":"if err := p.SendFile(ctx, rc, f); err != nil && strings.Contains(err.Error(), \"empty payload\") { log.Error(\"media bytes were empty; check upstream download\") }","preventionTips":["Always check attachment byte length before sending","Propagate download errors instead of passing empty buffers","Log payload sizes at send time for debugging"],"tags":["weixin","media","empty-payload","validation"],"backgroundTag":"empty-required-field","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}