jackwener/OpenCLI · error · CommandExecutionError
coupang add-to-cart evaluation failed: ${error?.message || e
Error message
coupang add-to-cart evaluation failed: ${error?.message || error} What it means
This CommandExecutionError wraps a failure of page.evaluate(buildAddToCartEvaluate(productId)) — i.e. the in-page script that performs add-to-cart threw or could not be evaluated. Common causes inside evaluate: the page DOM isn't what the script expects (selectors missing), the page navigated away mid-evaluation, or an exception raised inside the evaluated function. The library catches it and rethrows with the underlying message.
Source
Thrown at clis/coupang/add-to-cart.js:122
{ 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.');
}
if (!result?.ok) {
throw new CommandExecutionError('Failed to confirm add-to-cart success.');View on GitHub (pinned to 49907e53dc)
Solutions
- Check the wrapped message: 'Execution context was destroyed' means a redirect — add a wait/retry or block navigations during evaluate
- Update the library version if Coupang changed their page DOM; the evaluate script may need new selectors
- Load the product page manually and verify it's a normal, in-stock product page (not redirecting to sold-out/region error)
- Retry the command once — transient hydration timing often causes one-off evaluate failures
Example fix
// before
await page.goto(finalUrl);
const result = await page.evaluate(buildAddToCartEvaluate(productId)); // context destroyed by redirect
// after
await page.goto(finalUrl, { waitUntil: 'networkidle' });
await page.waitForSelector('.prod-atf, #addToCart', { timeout: 15000 });
const result = await page.evaluate(buildAddToCartEvaluate(productId)); Defensive patterns
Strategy: try-catch
Validate before calling
await page.goto(productUrl, { waitUntil: 'networkidle' });
const ready = await page.waitForSelector('.prod-atf, [data-testid="add-to-cart"]', { timeout: 15000 }).catch(() => null);
if (!ready) throw new Error('product page DOM not ready — do not run add-to-cart evaluate yet'); Type guard
function isEvaluateFailure(e) {
return /add-to-cart evaluation failed|Execution context was destroyed/i.test(e?.message || '');
} Try / catch
try {
await runCli('coupang add-to-cart', '--product-id', productId);
} catch (e) {
if (/Execution context was destroyed/.test(e.message)) {
// page redirected mid-evaluate: reload and retry once
return runCli('coupang add-to-cart', '--product-id', productId);
}
if (/evaluation failed/.test(e.message)) {
console.error('DOM may have changed; update the library or inspect the product page');
}
throw e;
} Prevention
- Wait for page hydration/networkidle before running the command on slow connections
- Distinguish 'context destroyed' (redirect — retry) from selector errors (DOM change — update library)
- Verify the product is in stock and doesn't redirect (sold-out/region pages)
- Keep the library updated as Coupang evolves its product-page DOM
When it happens
Trigger: `page.evaluate(...)` rejects after a successful goto: Execution context destroyed by a client-side redirect on the product page, an uncaught exception in buildAddToCartEvaluate's DOM logic (e.g. add-to-cart button/app state missing), or the page being navigated/closed during evaluation.
Common situations: Coupang changing their product-page DOM so the injected script's selectors throw, the product page auto-redirecting (sold out, region block) destroying the execution context, slow page load where the script runs before the app hydrates, or an out-of-stock item whose UI path errors.
Related errors
- coupang add-to-cart navigation failed: ${error?.message || e
- Failed to extract Booking.com cards: ${err?.message || err}
- ${label}: ${String(payload.error)}
- ${label} returned malformed extraction payload
- coupang product extraction failed: ${error?.message || error
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/6204c7f8f83eee7d.
Report an issue: GitHub.