xpzouying/xiaohongshu-mcp · error

下载图片失败 %s: %w

Error message

下载图片失败 %s: %w

What it means

ProcessImages processes an image list in order; for each URL-shaped image it downloads immediately via DownloadImage, and any download error aborts the whole batch with this wrapped error identifying the failing URL. Unlike DownloadImages (aggregate), this is fail-fast on the first bad image.

Source

Thrown at pkg/downloader/processor.go:35

		downloader: NewImageDownloader(configs.GetImagesPath()),
	}
}

// ProcessImages 处理图片列表,返回本地文件路径
// 支持两种输入格式:
// 1. URL格式 (http/https开头) - 自动下载到本地
// 2. 本地文件路径 - 直接使用
// 保持原始图片顺序,如果下载失败直接返回错误
func (p *ImageProcessor) ProcessImages(images []string) ([]string, error) {
	localPaths := make([]string, 0, len(images))

	// 按顺序处理每张图片
	for _, image := range images {
		if IsImageURL(image) {
			// URL图片:立即下载,失败直接返回错误
			localPath, err := p.downloader.DownloadImage(image)
			if err != nil {
				return nil, fmt.Errorf("下载图片失败 %s: %w", image, err)
			}
			localPaths = append(localPaths, localPath)
		} else {
			// 本地路径直接使用
			localPaths = append(localPaths, image)
		}
	}

	if len(localPaths) == 0 {
		return nil, fmt.Errorf("no valid images found")
	}

	return localPaths, nil
}

View on GitHub (pinned to 332d196854)

Solutions

  1. Check the wrapped error and the %s URL for reachability (curl -I) and fix or remove the bad URL
  2. Pre-validate all URLs with IsImageURL and an HTTP HEAD check before calling ProcessImages
  3. Switch the failing image to a local file path (non-URL entries bypass downloading)
  4. Add retry logic around ProcessImages for transient network errors

Example fix

// before
localPaths, err := processor.ProcessImages(ctx, images)
// after
for _, img := range images {
    if IsImageURL(img) && !reachable(img) { return fmt.Errorf("image unreachable: %s", img) }
}
localPaths, err := processor.ProcessImages(ctx, images)
Defensive patterns

Strategy: validation

Validate before calling

for _, img := range images {
    if IsImageURL(img) {
        resp, err := http.Head(img)
        if err != nil || resp.StatusCode >= 400 {
            return fmt.Errorf("image url unreachable: %s", img)
        }
    } else if _, err := os.Stat(img); err != nil {
        return fmt.Errorf("local image missing: %s", img)
    }
}

Try / catch

localPaths, err := processor.ProcessImages(ctx, images)
if err != nil {
    if strings.Contains(err.Error(), "下载图片失败") {
        return fmt.Errorf("pre-publish image download failed: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ProcessImages where an entry passes IsImageURL but DownloadImage fails — unreachable host, HTTP error, timeout, or invalid image content.

Common situations: Publishing Xiaohongshu content whose Markdown contains remote images hosted on dead or hotlink-protected CDNs; typos in image URLs; machine without internet access.

Related errors


AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05). Data as JSON: /api/errors/6cfde311172e6ecf. Report an issue: GitHub.