jackwener/OpenCLI · error · CommandExecutionError
Instagram media metadata returned an invalid download URL fo
Error message
Instagram media metadata returned an invalid download URL for item #${index + 1} What it means
Thrown by buildInstagramDownloadItems when item.url for a media entry cannot be parsed by new URL(String(item.url || '')). The metadata item exists and has a valid type, but its download URL is missing or unparseable.
Source
Thrown at clis/instagram/download.js:98
kind: kind,
shortcode,
canonicalUrl: `https://www.instagram.com/${kind}/${shortcode}/`,
};
}
export function buildInstagramDownloadItems(shortcode, items) {
if (!Array.isArray(items)) {
throw new CommandExecutionError('Instagram media metadata returned a malformed media list');
}
return items.map((item, index) => {
if (!item || typeof item !== 'object' || !['image', 'video'].includes(item.type)) {
throw new CommandExecutionError(`Instagram media metadata returned malformed media item #${index + 1}`);
}
let downloadUrl;
try {
downloadUrl = new URL(String(item.url || ''));
}
catch {
throw new CommandExecutionError(`Instagram media metadata returned an invalid download URL for item #${index + 1}`);
}
if (!['http:', 'https:'].includes(downloadUrl.protocol)) {
throw new CommandExecutionError(`Instagram media metadata returned an unsupported download URL for item #${index + 1}`);
}
const fallbackExt = item.type === 'video' ? '.mp4' : '.jpg';
let ext = fallbackExt;
const candidateExt = path.extname(downloadUrl.pathname).toLowerCase();
if (candidateExt && candidateExt.length <= 8)
ext = candidateExt;
return {
type: item.type,
url: downloadUrl.toString(),
filename: `${shortcode}_${String(index + 1).padStart(2, '0')}${ext}`,
};
});
}
export function buildInstagramFetchScript(shortcode) {
// The persisted GraphQL query this used to send now answers HTTP 200 withView on GitHub (pinned to 49907e53dc)
Solutions
- Re-run the command with a valid (logged-in if needed) browser session
- Retry later if Instagram is rate-limiting or returning degraded data
- Update the library if Instagram changed where the CDN URL lives in the metadata
Defensive patterns
Strategy: validation
Validate before calling
for (const item of items) {
let u; try { u = new URL(String(item.url || '')); } catch { throw new Error('Item has no parseable download URL; refetch metadata'); }
} Type guard
function hasDownloadUrl(item) {
if (!item || typeof item.url !== 'string') return false;
try { new URL(item.url); return true; } catch { return false; }
} Try / catch
try {
await igDownload(url);
} catch (e) {
if (/invalid download URL/.test(e.message)) {
console.error('A media item lacked a usable URL; retry with a fresh session.');
} else throw e;
} Prevention
- Retry metadata fetches that return partial data
- Keep sessions logged in so CDN URLs are fully populated
- Update the library if the metadata url field location changed
When it happens
Trigger: A media item whose url field is empty, null, or a relative/garbage string that new URL() rejects — often from an incomplete or degraded metadata fetch inside the browser page.
Common situations: Instagram serving partial CDN data when logged out or rate-limited; items where the video/image rendition URL failed to build in the page script; API shape changes removing the url field.
Related errors
- Instagram media metadata returned a malformed media list
- Instagram media metadata returned malformed media item #${in
- Instagram media metadata returned an unsupported download UR
- Twitter reply completion returned a malformed status url.
- Unexpected 12306 probe: ${JSON.stringify(probe)}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/187812e38e074304.
Report an issue: GitHub.