jackwener/OpenCLI · error · ArgumentError

${label} must be a Coupang product URL containing /vp/produc

Error message

${label} must be a Coupang product URL containing /vp/products/<id>

What it means

requireProductIdArg validates the --url argument in the Coupang adapter. When the label is '--url', it tries to parse the value as a URL and extract an id from a /vp/products/<id> path on a coupang.com host; if parsing fails, the host is not Coupang, or the path does not match, it throws this ArgumentError. The library fails fast with a typed error instead of proceeding with an unusable product URL.

Source

Thrown at clis/coupang/utils.js:113

        return '';
    const match = text.match(/\/vp\/products\/(\d+)/) || text.match(/\b(\d{6,})\b/);
    return match?.[1] ?? '';
}
export function requireProductIdArg(raw, label = '--product-id') {
    const text = asString(raw);
    if (label === '--url') {
        try {
            const url = new URL(text.startsWith('http') ? text : `https://www.coupang.com${text}`);
            const match = url.pathname.match(/^\/vp\/products\/(\d{6,})(?:\/|$)/);
            const isCoupangHost = url.hostname === 'coupang.com' || url.hostname.endsWith('.coupang.com');
            if (isCoupangHost && match) {
                return match[1];
            }
        }
        catch {
            // Fall through to the typed validation error below.
        }
        throw new ArgumentError(`${label} must be a Coupang product URL containing /vp/products/<id>`);
    }
    if (!/^\d{6,}$/.test(text)) {
        throw new ArgumentError(`${label} must be a numeric Coupang product ID`);
    }
    return text;
}
export function canonicalizeProductUrl(rawUrl, productId) {
    const raw = asString(rawUrl);
    if (raw) {
        try {
            const url = new URL(raw.startsWith('http') ? raw : `https://www.coupang.com${raw}`);
            if (!url.hostname.includes('coupang.com'))
                return '';
            const id = normalizeProductId(url.pathname) || normalizeProductId(productId);
            if (!id)
                return url.toString();
            return `https://www.coupang.com/vp/products/${id}`;
        }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open the product detail page and copy the canonical URL of the form https://www.coupang.com/vp/products/<id>.
  2. If you already know the numeric ID, pass it with --product-id instead of --url; the numeric branch only requires 6+ digits.
  3. Verify the URL host is coupang.com or *.coupang.com and the path starts with /vp/products/ followed by at least 6 digits.
  4. Use normalizeProductId() as a pre-check; it also accepts bare 6+ digit ids embedded in text.

Example fix

// before
await cli.coupang.product({ url: 'https://www.coupang.com/np/12345678' });
// after
await cli.coupang.product({ url: 'https://www.coupang.com/vp/products/12345678' });
// or: await cli.coupang.product({ productId: '12345678' });
Defensive patterns

Strategy: validation

Validate before calling

function isValidCoupangProductUrl(u) {
  try {
    const url = new URL(u.startsWith('http') ? u : `https://www.coupang.com${u}`);
    const isCoupang = url.hostname === 'coupang.com' || url.hostname.endsWith('.coupang.com');
    return isCoupang && /^\/vp\/products\/\d{6,}(?:\/|$)/.test(url.pathname);
  } catch { return false; }
}
if (!isValidCoupangProductUrl(myUrl)) throw new Error('need a coupang.com /vp/products/<id> URL');

Type guard

function isCoupangProductUrl(v) {
  if (typeof v !== 'string') return false;
  try {
    const url = new URL(v);
    return (url.hostname === 'coupang.com' || url.hostname.endsWith('.coupang.com'))
      && /^\/vp\/products\/\d{6,}/.test(url.pathname);
  } catch { return false; }
}

Try / catch

try {
  await cli.coupang.product({ url });
} catch (e) {
  if (e instanceof ArgumentError && e.message.includes('/vp/products/')) {
    console.error('Pass a canonical URL like https://www.coupang.com/vp/products/<id>, or use --product-id.');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling a Coupang command with --url set to: a non-URL string, a malformed URL (e.g. 'htp://...'), a URL on a non-Coupang domain, a Coupang URL whose path is not /vp/products/<6+ digits> (e.g. a search page /search?q=... or a category page), or an id shorter than 6 digits in the path.

Common situations: Pasting a mobile Coupang link (m.coupang.com) with a different path shape, copying a shortened or affiliate redirect URL, passing a Coupang search/results page instead of a product detail page, or forgetting the https:// prefix in a way that breaks URL parsing.

Related errors


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