{"record":{"id":"1f5b0b07bc5b426f","repo":"chenhg5/cc-connect","slug":"weixin-empty-file","errorCode":null,"errorMessage":"weixin: empty file","messagePattern":"weixin: empty file","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/weixin/media_outbound.go","lineNumber":197,"sourceCode":"\t\t\tMedia: &cdnMedia{\n\t\t\t\tEncryptQueryParam: ref.downloadParam,\n\t\t\t\tAESKey:            formatAesKeyForAPI(ref.aesKey),\n\t\t\t\tEncryptType:       1,\n\t\t\t},\n\t\t\tMidSize: ref.cipherSize,\n\t\t},\n\t}\n\treturn p.sendSingleItem(ctx, rc, item)\n}\n\n// SendFile implements core.FileSender.\nfunc (p *Platform) SendFile(ctx context.Context, replyCtx any, file core.FileAttachment) error {\n\trc, err := p.resolveReplyContext(replyCtx)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(file.Data) == 0 {\n\t\treturn fmt.Errorf(\"weixin: empty file\")\n\t}\n\tname := strings.TrimSpace(file.FileName)\n\tif name == \"\" {\n\t\tname = \"file.bin\"\n\t}\n\n\tif isVideoFile(file) {\n\t\tref, err := p.uploadToWeixinCDN(ctx, rc.peerUserID, file.Data, uploadMediaVideo, \"SendFileVideo\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn p.sendSingleItem(ctx, rc, buildVideoMessageItem(ref))\n\t}\n\n\tref, err := p.uploadToWeixinCDN(ctx, rc.peerUserID, file.Data, uploadMediaFile, \"SendFile\")\n\tif err != nil {\n\t\treturn err\n\t}","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/weixin/media_outbound.go#L179-L215","documentation":"Validation guard in Weixin SendFile: the file attachment's Data slice has zero length, so nothing can be uploaded; the caller produced an empty file attachment.","triggerScenarios":"Calling SendFile with core.FileAttachment{Data: nil} or an empty byte slice.","commonSituations":"os.ReadFile returned 0 bytes for an empty or unreadable-but-not-erroring file; caller constructed the attachment from a nil slice after a failed export.","solutions":["Check len(file.Data) > 0 before calling SendFile.","Verify the source file exists and is non-empty (os.Stat) before reading.","Handle read errors so failures don't surface as empty data."],"exampleFix":"// before\ndata, _ := os.ReadFile(path)\np.SendFile(ctx, rc, core.FileAttachment{FileName: name, Data: data}) // weixin: empty file\n// after\ndata, err := os.ReadFile(path)\nif err != nil || len(data) == 0 { return fmt.Errorf(\"read %s: %w\", path, err) }","handlingStrategy":"validation","validationCode":"if len(file.Data) == 0 { return errors.New(\"file attachment is empty; skipping send\") }","typeGuard":null,"tryCatchPattern":"if err := p.SendFile(ctx, rc, f); err != nil && strings.Contains(err.Error(), \"empty file\") { log.Error(\"empty file bytes for\", \"name\", f.FileName) }","preventionTips":["Stat source files for size > 0 before reading","Handle os.ReadFile errors explicitly","Validate attachments at construction time, not at send time"],"tags":["weixin","file","validation","empty-data"],"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"}