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
- Read the wrapped error message for the root cause (net::ERR_NAME_NOT_RESOLVED, Timeout 30000ms exceeded, etc.) and address that specifically
- Increase the navigation timeout: page.goto(finalUrl, { timeout: 60000, waitUntil: 'domcontentloaded' }) in your wrapper or pass a larger timeout to the command if supported
- Verify the product id/URL is valid — navigate manually in Chrome to confirm the product page loads
- 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
- Pre-check the product URL loads in a normal browser before automating
- Use longer timeouts / waitUntil:'domcontentloaded' in custom wrappers
- Retry once on transient net::ERR or timeout errors
- Ensure the driven Chrome instance has network access (proxy/VPN)
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
- coupang add-to-cart evaluation failed: ${error?.message || e
- Discord did not finish navigating to the requested channel.
- Unexpected 12306 probe: ${JSON.stringify(probe)}
- Failed to load Booking.com search page: ${err?.message || er
- ChatGPT did not create a conversation URL after sending the
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/1507e0a8a44d81c1.
Report an issue: GitHub.