{"record":{"id":"405dc931cef37ff2","repo":"xpzouying/xiaohongshu-mcp","slug":"d-405dc9","errorCode":null,"errorMessage":"第%d张图片上传超时","messagePattern":"第(.+?)张图片上传超时","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/publish.go","lineNumber":264,"sourceCode":"\t\tvalidPaths = append(validPaths, path)\n\t\tlogrus.Infof(\"获取有效图片：%s\", path)\n\t}\n\n\t// 逐张上传：每张上传后等待预览出现，再上传下一张\n\tfor i, path := range validPaths {\n\t\tuploadInput, err := findImageUploadInput(page, i == 0)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"查找上传输入框失败(第%d张)\", i+1)\n\t\t}\n\t\tif err := uploadInput.SetFiles([]string{path}); err != nil {\n\t\t\treturn errors.Wrapf(err, \"上传第%d张图片失败\", i+1)\n\t\t}\n\n\t\tslog.Info(\"图片已提交上传\", \"index\", i+1, \"path\", path)\n\n\t\t// 等待当前图片上传完成（预览元素数量达到 i+1），最多等 60 秒\n\t\tif err := waitForUploadComplete(page, i+1); err != nil {\n\t\t\treturn errors.Wrapf(err, \"第%d张图片上传超时\", i+1)\n\t\t}\n\t\ttime.Sleep(1 * time.Second)\n\t}\n\n\treturn nil\n}\n\n// findImageUploadInput 查找图片上传的输入框\nfunc findImageUploadInput(page *rod.Page, first bool) (*rod.Element, error) {\n\tif first {\n\t\treturn page.Element(\".upload-input\")\n\t}\n\n\tinputs, err := page.Elements(`input[type=\"file\"]`)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(inputs) == 0 {","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/publish.go#L246-L282","documentation":"This error wraps a timeout raised by waitForUploadComplete: after submitting an image to the Xiaohongshu creator upload input, the library polls the page for .img-preview-area .pr preview elements for up to 60 seconds. If the number of preview thumbnails never reaches the expected count, the upload is considered failed and this error is returned to Publish with the 1-based image index.","triggerScenarios":"Calling Publish with images where a submitted file never produces a preview element within 60s — e.g. waitForUploadComplete(page, i+1) returns errors.Errorf after the 60s poll loop in uploadImages (xiaohongshu/publish.go:264).","commonSituations":"Slow/unstable network uplink; very large images (multi-MB HEIC/raw files); Xiaohongshu page DOM changed so .img-preview-area .pr no longer matches; upload rejected server-side (bad format, quota); the browser page was closed or navigated mid-upload.","solutions":["Check network connectivity and upload bandwidth; retry on a stable connection","Compress/resize images (e.g. convert HEIC to JPEG, keep under a few MB) before calling Publish","Verify the file exists and is a supported format (the library silently skips nonexistent paths, so a wrong path can shift indexes)","Inspect the creator page to confirm the preview selector .img-preview-area .pr still matches the current DOM; update the selector if the site changed","Increase the 60s maxWaitTime in waitForUploadComplete if uploads are legitimately slow"],"exampleFix":"// before\nimages := []string{\"/photos/IMG_0001.heic\"}\nerr := bot.Publish(ctx, post, images)\n// after\njpegPath, _ := convertToJPEG(\"/photos/IMG_0001.heic\") // downscale + convert\nimages := []string{jpegPath}\nerr := bot.Publish(ctx, post, images)","handlingStrategy":"validation","validationCode":"for _, p := range images {\n    info, err := os.Stat(p)\n    if err != nil { return fmt.Errorf(\"图片不存在: %s\", p) }\n    if info.Size() > 10<<20 { return fmt.Errorf(\"图片过大(%dMB), 请压缩: %s\", info.Size()>>20, p) }\n}","typeGuard":null,"tryCatchPattern":"err := bot.Publish(ctx, post, images)\nif err != nil && strings.Contains(err.Error(), \"上传超时\") {\n    // 压缩图片后重试一次\n}","preventionTips":["Pre-compress/convert images to JPEG/WebP under a few MB","Pre-check file existence and size before calling Publish","Ensure a stable network connection for uploads","Keep the library's DOM selectors up to date with the site"],"tags":["upload","timeout","network","browser-automation"],"backgroundTag":"upload-timeout","analyzedSha":"332d196854a9eac0d2b8c2c0e3d0cc43139d724c","analyzedAt":"2026-09-05T22:22:55.988Z","contentChangedAt":"2026-09-05T22:22:55.988Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}