jackwener/OpenCLI · error · CommandExecutionError
Failed to download pin ${id}: ${result.error || 'unknown err
Error message
Failed to download pin ${id}: ${result.error || 'unknown error'} What it means
httpDownload completed without throwing but reported result.success === false; the command raises CommandExecutionError using result.error, or 'unknown error' if none was provided. This is an in-band download failure (e.g. non-2xx status, content mismatch) rather than an exception.
Source
Thrown at clis/pinterest/download.js:54
throw new EmptyResultError('pinterest download', `pin "${id}" not found`);
}
const imageUrl = pickPinImage(pin.images);
if (!imageUrl) {
throw new CommandExecutionError(`Pin ${id} has no downloadable image (it may be a video or story pin)`);
}
fs.mkdirSync(output, { recursive: true });
const ext = path.extname(new URL(imageUrl).pathname) || '.jpg';
const destPath = path.join(output, `${id}${ext}`);
let result;
try {
result = await httpDownload(imageUrl, destPath, { timeout: 60000 });
} catch (err) {
throw new CommandExecutionError(`Failed to download pin ${id}: ${getErrorMessage(err)}`);
}
if (!result.success) {
throw new CommandExecutionError(`Failed to download pin ${id}: ${result.error || 'unknown error'}`);
}
return [{
pinId: id,
status: 'success',
size: formatBytes(result.size),
path: destPath,
}];
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Re-resolve the pin to get a fresh image URL and retry — CDN URLs can expire.
- Read result.error in the message for the specific HTTP status and address it.
- Add delays/backoff between downloads to avoid rate limiting.
- Retry with a different image rendition from pin.images if available.
Example fix
// before
await cli.download(pinId); // stale image URL 403s
// after
try { await cli.download(pinId); } catch (e) { const pin = await reFetch(pinId); await cli.download(pin.id); } Defensive patterns
Strategy: retry
Validate before calling
const head = await fetch(imageUrl, { method: 'HEAD' });
if (!head.ok) console.warn(`image URL unhealthy: HTTP ${head.status}`); Type guard
null
Try / catch
try {
await cli.download(pinId);
} catch (e) {
if (/Failed to download pin/.test(e.message) && !/timed out/.test(e.message)) {
const pin = await refreshPin(pinId); // get fresh CDN URL
await cli.download(pin.id);
} else throw e;
} Prevention
- Re-resolve pins to get fresh CDN URLs before retrying
- Throttle batch downloads to avoid CDN rate limits
- Read the embedded result.error for the HTTP status
- Fall back to a different image rendition when one 403s
When it happens
Trigger: Image server returning HTTP 403/404 for the CDN URL; expired or signed-URL mismatch; server returning an HTML error page instead of the image; result.error set by the downloader on bad status codes.
Common situations: Hotlink protection or geo-blocking on the image CDN; picking an old cached image URL that was purged; rate-limited requests after batch scraping.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- 字幕获取失败: ${items.error}${items.text ? ' — ' + items.text : ''
- Failed to download pin ${id}: ${getErrorMessage(err)}
- Pinterest request failed (HTTP ${status})${detail}${hint}
- HTTP ${res.status} from signed CDN URL while downloading ${i
- API_ERROR
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/97297625b424436d.
Report an issue: GitHub.