{"record":{"id":"6e3f90629435feca","repo":"jackwener/OpenCLI","slug":"label-must-be-a-numeric-coupang-product-id","errorCode":null,"errorMessage":"${label} must be a numeric Coupang product ID","messagePattern":"(.+?) must be a numeric Coupang product ID","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/coupang/utils.js","lineNumber":116,"sourceCode":"}\nexport function requireProductIdArg(raw, label = '--product-id') {\n    const text = asString(raw);\n    if (label === '--url') {\n        try {\n            const url = new URL(text.startsWith('http') ? text : `https://www.coupang.com${text}`);\n            const match = url.pathname.match(/^\\/vp\\/products\\/(\\d{6,})(?:\\/|$)/);\n            const isCoupangHost = url.hostname === 'coupang.com' || url.hostname.endsWith('.coupang.com');\n            if (isCoupangHost && match) {\n                return match[1];\n            }\n        }\n        catch {\n            // Fall through to the typed validation error below.\n        }\n        throw new ArgumentError(`${label} must be a Coupang product URL containing /vp/products/<id>`);\n    }\n    if (!/^\\d{6,}$/.test(text)) {\n        throw new ArgumentError(`${label} must be a numeric Coupang product ID`);\n    }\n    return text;\n}\nexport function canonicalizeProductUrl(rawUrl, productId) {\n    const raw = asString(rawUrl);\n    if (raw) {\n        try {\n            const url = new URL(raw.startsWith('http') ? raw : `https://www.coupang.com${raw}`);\n            if (!url.hostname.includes('coupang.com'))\n                return '';\n            const id = normalizeProductId(url.pathname) || normalizeProductId(productId);\n            if (!id)\n                return url.toString();\n            return `https://www.coupang.com/vp/products/${id}`;\n        }\n        catch {\n            return '';\n        }","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/coupang/utils.js#L98-L134","documentation":"requireProductIdArg validates the --product-id argument: after handling the --url branch, it requires the value to be a purely numeric string of at least 6 digits (Coupang product IDs). Anything else (letters, spaces, short numbers, embedded IDs) throws this ArgumentError so callers get a typed failure instead of a bogus network request.","triggerScenarios":"Passing --product-id with: a Coupang URL instead of the bare ID (the URL branch only runs for label '--url'), a number shorter than 6 digits, an alphanumeric or whitespace-padded value like ' 1234567 ' is fine but 'abc123456' is not, or an empty/undefined value.","commonSituations":"Copying the whole product URL into the --product-id flag, truncating the ID when copying, using an internal SKU/vendor code that is not the Coupang product ID, or shell quoting issues that leave the flag empty.","solutions":["Pass only the numeric product ID (6+ digits), e.g. --product-id 1234567890.","If you have a URL, either use the --url flag (which parses /vp/products/<id>) or extract the ID with normalizeProductId() first.","Pre-validate with /^\\d{6,}$/ before calling the API.","Check that the value is not an option-prefixed or quoted-empty string in your shell invocation."],"exampleFix":"// before\nawait cli.coupang.product({ productId: 'https://www.coupang.com/vp/products/81543202' });\n// after\nawait cli.coupang.product({ productId: '81543202' });","handlingStrategy":"validation","validationCode":"function requireNumericProductId(v) {\n  const s = String(v ?? '').trim();\n  if (!/^\\d{6,}$/.test(s)) throw new Error(`--product-id must be 6+ digits, got: ${v}`);\n  return s;\n}\nconst productId = requireNumericProductId(rawProductId);","typeGuard":"function isNumericProductId(v) {\n  return typeof v === 'string' && /^\\d{6,}$/.test(v.trim());\n}","tryCatchPattern":"try {\n  await cli.coupang.product({ productId });\n} catch (e) {\n  if (e instanceof ArgumentError && e.message.includes('numeric Coupang product ID')) {\n    const extracted = normalizeProductId(productId) || normalizeProductId(url);\n    if (extracted) return cli.coupang.product({ productId: extracted });\n  }\n  throw e;\n}","preventionTips":["Never paste a URL into --product-id; use --url for URLs.","Extract IDs with a /\\b(\\d{6,})\\b/ regex when working from links or logs.","Trim and type-check the value before calling.","Watch for shell quoting that truncates or empties the argument."],"tags":["argument-validation","coupang","input-format"],"backgroundTag":"invalid-argument-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}