jackwener/OpenCLI · error · ArgumentError
Unsupported URL protocol: ${url.protocol}
Error message
Unsupported URL protocol: ${url.protocol} What it means
Thrown by parseInstagramMediaTarget when the raw string parses as a URL but uses a protocol other than http: or https:. Only web URLs are accepted for Instagram media links. The offending protocol is included in the message.
Source
Thrown at clis/instagram/download.js:56
if (mediaId > MAX_INSTAGRAM_MEDIA_ID) return '';
}
if (mediaId <= 0n) return '';
return mediaId.toString();
}
export function parseInstagramMediaTarget(input) {
const raw = String(input || '').trim();
if (!raw) {
throw new ArgumentError('Instagram URL is required', 'Expected https://www.instagram.com/p/... or https://www.instagram.com/reel/...');
}
let url;
try {
url = new URL(raw);
}
catch {
throw new ArgumentError(`Invalid Instagram URL: ${raw}`, 'Expected https://www.instagram.com/p/<shortcode>/ or /reel/<shortcode>/');
}
if (!['http:', 'https:'].includes(url.protocol)) {
throw new ArgumentError(`Unsupported URL protocol: ${url.protocol}`);
}
const host = url.hostname.toLowerCase();
if (host !== INSTAGRAM_HOST_SUFFIX && !host.endsWith(`.${INSTAGRAM_HOST_SUFFIX}`)) {
throw new ArgumentError(`Unsupported host: ${host}`, 'Only instagram.com URLs are supported');
}
const segments = url.pathname.split('/').filter(Boolean);
let kind;
let shortcode;
if (segments.length >= 2 && SUPPORTED_KINDS.has(segments[0])) {
kind = segments[0];
shortcode = segments[1];
}
else if (segments.length >= 3 && SUPPORTED_KINDS.has(segments[1])) {
kind = segments[1];
shortcode = segments[2];
}
if (!kind || !shortcode) {
throw new ArgumentError(`Unsupported Instagram media URL: ${raw}`, 'Only /p/<shortcode>/, /reel/<shortcode>/, and /tv/<shortcode>/ links are supported');View on GitHub (pinned to 49907e53dc)
Solutions
- Use an https:// Instagram URL (http:// also accepted)
- Convert app deep links (instagram://media?...) to their https://www.instagram.com equivalent
- Validate the scheme in your own wrapper before invoking the CLI
Example fix
// before instagram://media?id=Cxyz123 // after https://www.instagram.com/p/Cxyz123/
Defensive patterns
Strategy: validation
Validate before calling
const u = new URL(raw);
if (u.protocol !== 'https:' && u.protocol !== 'http:') throw new Error(`Use an https:// Instagram URL, got ${u.protocol}`); Type guard
function isWebUrl(v) {
try { const u = new URL(v); return u.protocol === 'http:' || u.protocol === 'https:'; } catch { return false; }
} Try / catch
try {
await igDownload(raw);
} catch (e) {
if (e.name === 'ArgumentError' && /Unsupported URL protocol/.test(e.message)) {
console.error('Convert app deep links (instagram://) to https://www.instagram.com URLs before downloading.');
} else throw e;
} Prevention
- Never pass instagram:// deep links from mobile share sheets
- Normalize schemes to https:// in wrapper scripts
- Test input parsing with non-http schemes
When it happens
Trigger: Passing an instagram: app-scheme link, ftp://, file://, or a URL built with javascript:/data: scheme to the download target.
Common situations: Copying an 'instagram://' deep link from the mobile app share sheet; programmatically constructing URLs with a wrong scheme; tests feeding file:// fixtures.
Related errors
- --url must be a Discord channel URL like https://discord.com
- --url must be a Discord thread/post URL like https://discord
- id not a valid Grok URL (got "${input}")
- event query parameter must be a numeric event id
- event must be an event id, an /events/:id URL, a stats URL w
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/48fea79419949404.
Report an issue: GitHub.