jackwener/OpenCLI · error · CommandExecutionError

coupang add-to-cart navigation failed: ${error?.message || e

Error message

coupang add-to-cart navigation failed: ${error?.message || error}

What it means

This CommandExecutionError wraps a failure of page.goto(finalUrl) during the coupang add-to-cart flow. The Playwright navigation itself rejected (timeout, net::ERR_*, navigation interrupted) and the library catches it and rethrows with the underlying message. It means the browser never successfully loaded the product page, so the add-to-cart script could not run.

Source

Thrown at clis/coupang/add-to-cart.js:119

    strategy: Strategy.COOKIE,
    browser: true,
    args: [
        { name: 'product-id', positional: true, required: false, help: 'Coupang product ID' },
        { name: 'url', required: false, help: 'Canonical product URL' },
    ],
    columns: ['ok', 'product_id', 'url', 'message'],
    func: async (page, kwargs) => {
        const rawProductId = kwargs['product-id'];
        if (!rawProductId && !kwargs.url) {
            throw new ArgumentError('Either --product-id or --url is required');
        }
        const productId = rawProductId
            ? requireProductIdArg(rawProductId, 'product-id')
            : requireProductIdArg(kwargs.url, '--url');
        const targetUrl = canonicalizeProductUrl(kwargs.url, productId);
        const finalUrl = targetUrl || canonicalizeProductUrl('', productId);
        await page.goto(finalUrl).catch((error) => {
            throw new CommandExecutionError(`coupang add-to-cart navigation failed: ${error?.message || error}`);
        });
        const result = await page.evaluate(buildAddToCartEvaluate(productId)).catch((error) => {
            throw new CommandExecutionError(`coupang add-to-cart evaluation failed: ${error?.message || error}`);
        });
        const loginHints = result?.loginHints ?? {};
        if (loginHints.hasLoginLink && !loginHints.hasMyCoupang) {
            throw new AuthRequiredError('coupang.com', 'Please log into Coupang in Chrome and retry.');
        }
        const actualProductId = normalizeProductId(result?.currentProductId || productId);
        if (result?.reason === 'PRODUCT_MISMATCH') {
            const observed = actualProductId ? `got ${actualProductId}` : 'no product id observed';
            throw new CommandExecutionError(`Product mismatch: expected ${productId}, ${observed}`);
        }
        if (result?.reason === 'OPTION_REQUIRED') {
            throw new CommandExecutionError('This product requires option selection and is not supported in v1.');
        }
        if (result?.reason === 'ADD_TO_CART_BUTTON_NOT_FOUND') {
            throw new CommandExecutionError('Could not find an add-to-cart button on the product page.');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the wrapped error message for the root cause (net::ERR_NAME_NOT_RESOLVED, Timeout 30000ms exceeded, etc.) and address that specifically
  2. Increase the navigation timeout: page.goto(finalUrl, { timeout: 60000, waitUntil: 'domcontentloaded' }) in your wrapper or pass a larger timeout to the command if supported
  3. Verify the product id/URL is valid — navigate manually in Chrome to confirm the product page loads
  4. Check network/proxy/VPN issues and ensure the Chrome instance the command drives has internet access

Example fix

// before
await page.goto(finalUrl); // flaky timeout on slow network
// after
await page.goto(finalUrl, { timeout: 60000, waitUntil: 'domcontentloaded' });
Defensive patterns

Strategy: retry

Validate before calling

const productId = '1234567890';
if (!/^\d+$/.test(productId)) throw new Error('product-id must be numeric digits');
const probe = await fetch(`https://www.coupang.com/vp/products/${productId}`, { method: 'HEAD' });
if (!probe.ok) throw new Error(`product page not reachable: HTTP ${probe.status}`);

Type guard

function isNavFailure(e) {
  return /add-to-cart navigation failed|net::ERR|Timeout \d+ms exceeded/i.test(e?.message || '');
}

Try / catch

try {
  await runCli('coupang add-to-cart', '--product-id', productId);
} catch (e) {
  if (isNavFailure(e)) {
    await new Promise(r => setTimeout(r, 5000));
    return runCli('coupang add-to-cart', '--product-id', productId);
  }
  throw e;
}

Prevention

When it happens

Trigger: `page.goto(finalUrl)` rejects: network timeout (default 30s), DNS failure, connection reset, net::ERR_ABORTED from a redirect/download, invalid finalUrl produced by canonicalizeProductUrl from a malformed --url, or the browser/page being closed mid-navigation.

Common situations: Slow or blocked network, Coupang bot protection aborting the navigation, a malformed product URL string passed as --url that canonicalization couldn't fix, page closed by prior code, or flaky corporate proxy causing timeouts.

Related errors


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