{"record":{"id":"3616cd3cf94c5757","repo":"jackwener/OpenCLI","slug":"either-product-id-or-url-is-required","errorCode":null,"errorMessage":"Either --product-id or --url is required","messagePattern":"Either --product-id or --url is required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/coupang/add-to-cart.js","lineNumber":111,"sourceCode":"  `;\n}\ncli({\n    site: 'coupang',\n    name: 'add-to-cart',\n    access: 'write',\n    description: 'Add a Coupang product to cart using logged-in browser session',\n    domain: 'www.coupang.com',\n    strategy: Strategy.COOKIE,\n    browser: true,\n    args: [\n        { name: 'product-id', positional: true, required: false, help: 'Coupang product ID' },\n        { name: 'url', required: false, help: 'Canonical product URL' },\n    ],\n    columns: ['ok', 'product_id', 'url', 'message'],\n    func: async (page, kwargs) => {\n        const rawProductId = kwargs['product-id'];\n        if (!rawProductId && !kwargs.url) {\n            throw new ArgumentError('Either --product-id or --url is required');\n        }\n        const productId = rawProductId\n            ? requireProductIdArg(rawProductId, 'product-id')\n            : requireProductIdArg(kwargs.url, '--url');\n        const targetUrl = canonicalizeProductUrl(kwargs.url, productId);\n        const finalUrl = targetUrl || canonicalizeProductUrl('', productId);\n        await page.goto(finalUrl).catch((error) => {\n            throw new CommandExecutionError(`coupang add-to-cart navigation failed: ${error?.message || error}`);\n        });\n        const result = await page.evaluate(buildAddToCartEvaluate(productId)).catch((error) => {\n            throw new CommandExecutionError(`coupang add-to-cart evaluation failed: ${error?.message || error}`);\n        });\n        const loginHints = result?.loginHints ?? {};\n        if (loginHints.hasLoginLink && !loginHints.hasMyCoupang) {\n            throw new AuthRequiredError('coupang.com', 'Please log into Coupang in Chrome and retry.');\n        }\n        const actualProductId = normalizeProductId(result?.currentProductId || productId);\n        if (result?.reason === 'PRODUCT_MISMATCH') {","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/coupang/add-to-cart.js#L93-L129","documentation":"This ArgumentError is a client-side precondition check in the coupang add-to-cart command: the caller must supply either --product-id or --url so the command can determine which product to add. If both are absent there is no way to build the target product URL, so the command fails fast before any browser navigation. Note that when only --product-id is given, --url may be omitted (the URL is derived).","triggerScenarios":"Running the coupang add-to-cart command's func with kwargs where both kwargs['product-id'] and kwargs.url are undefined/empty — i.e. invoking the CLI with neither flag (or with empty-string values), e.g. `coupang add-to-cart` with no arguments.","commonSituations":"Forgetting flags in a scripted invocation, passing flags with misspelled names (e.g. --productid or --product_id instead of --product-id), or environment variable interpolation producing empty strings for both options.","solutions":["Pass --product-id with the Coupang product number, e.g. --product-id 1234567890","Or pass --url with the canonical product URL, e.g. --url 'https://www.coupang.com/vp/products/1234567890'","Check flag spelling and that shell variables expanding into the flags are non-empty","Prefer --product-id when you have it; URL extraction is stricter about URL format"],"exampleFix":"// before\nawait runCli('coupang add-to-cart'); // ArgumentError\n// after\nawait runCli('coupang add-to-cart', '--product-id', '1234567890');","handlingStrategy":"validation","validationCode":"const productId = process.env.COUPANG_PRODUCT_ID;\nconst url = process.env.COUPANG_URL;\nif (!productId && !url) throw new Error('Set COUPANG_PRODUCT_ID or COUPANG_URL before invoking coupang add-to-cart');","typeGuard":"function hasCoupangTarget(args) {\n  return Boolean(args && (args['product-id'] || args.url));\n}","tryCatchPattern":"try {\n  await runCli('coupang add-to-cart', ...args);\n} catch (e) {\n  if (/Either --product-id or --url is required/.test(e.message)) {\n    console.error('Usage: coupang add-to-cart --product-id <id> | --url <productUrl>');\n    process.exitCode = 2;\n    return;\n  }\n  throw e;\n}","preventionTips":["Build invocations from explicit variables and assert they are non-empty before exec","Use exact flag names: --product-id (hyphenated), --url","Prefer --product-id; it avoids URL-format pitfalls","Add a CLI usage check in wrapper scripts before invoking"],"tags":["argument-error","missing-argument","coupang","cli","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}