xpzouying/xiaohongshu-mcp · error
downloaded file is not a valid image
Error message
downloaded file is not a valid image
What it means
After downloading, DownloadImage uses the filetype package to sniff the bytes; if filetype.IsImage fails it returns 'downloaded file is not a valid image'. This catches cases where the server responded 200 but the body is not an image (HTML error page, JSON, verification page, etc.).
Source
Thrown at pkg/downloader/images.go:86
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("download failed with status %d for URL: %s", resp.StatusCode, imageURL)
}
// 读取图片数据
imageData, err := io.ReadAll(resp.Body)
if err != nil {
return "", errors.Wrap(err, "failed to read image data")
}
// 检测图片格式
kind, err := filetype.Match(imageData)
if err != nil {
return "", errors.Wrap(err, "failed to detect file type")
}
if !filetype.IsImage(imageData) {
return "", errors.New("downloaded file is not a valid image")
}
// 生成唯一文件名
fileName := d.generateFileName(imageURL, kind.Extension)
filePath := filepath.Join(d.savePath, fileName)
// 如果文件已存在,直接返回路径
if _, err := os.Stat(filePath); err == nil {
return filePath, nil
}
// 保存到文件
if err := os.WriteFile(filePath, imageData, 0644); err != nil {
return "", errors.Wrap(err, "failed to save image")
}
return filePath, nil
}View on GitHub (pinned to 332d196854)
Solutions
- Set proper User-Agent and Referer headers on the downloader (the library already sends UA/Referer; verify they match the site's expectations)
- Log the first bytes / content-type of the response to identify what the server actually returned
- Re-extract a fresh image URL (CDN links expire) and retry the download
- Handle the error per-image: skip the invalid one and continue the batch
Example fix
// before
path, err := downloader.DownloadImage(url)
if err != nil { return err }
// after
path, err := downloader.DownloadImage(url)
if err != nil {
if strings.Contains(err.Error(), "not a valid image") {
log.Printf("non-image response for %s, refreshing URL", url)
continue
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check response content type if you control the request
req.Header.Set("Referer", "https://www.xiaohongshu.com/") Try / catch
path, err := downloader.DownloadImage(url)
if err != nil && strings.Contains(err.Error(), "not a valid image") {
log.Printf("non-image body for %s, refreshing URL", url)
continue // skip or re-fetch fresh CDN link
} Prevention
- Send site-appropriate User-Agent and Referer headers
- Detect anti-bot/verify pages early and refresh session
- Treat per-image failures as skippable in batch downloads
When it happens
Trigger: Downloading an image URL that returns a 200 response with HTML/JSON body — e.g. an anti-bot page, expired CDN link, or login redirect page. The check at pkg/downloader/images.go:86 `if !filetype.IsImage(imageData)` triggers.
Common situations: CDN URL expired and returns an XML/HTML error with status 200; XHS serves a captcha/verify page instead of the image; downloading with missing Referer/UA so the server returns a block page; saving an SVG/webp variant the sniffer doesn't classify as image.
Related errors
- invalid image URL format
- 图片不能为空
- 视频不能为空
- 下载内置浏览器失败: %w 本项目只用内置浏览器,缺它不继续。请检查网络后重试; 离线环境可手动下载 %s,解压
- 校验失败: %w
AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05).
Data as JSON: /api/errors/4183cafe923b233f.
Report an issue: GitHub.