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

  1. Use an https:// Instagram URL (http:// also accepted)
  2. Convert app deep links (instagram://media?...) to their https://www.instagram.com equivalent
  3. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/48fea79419949404. Report an issue: GitHub.