{"record":{"id":"e1343eb27c51adff","repo":"jackwener/OpenCLI","slug":"xianyu-publish-label-must-be-a-positive-price-w","errorCode":null,"errorMessage":"xianyu publish ${label} must be a positive price with at most 2 decimals","messagePattern":"xianyu publish (.+?) must be a positive price with at most 2 decimals","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/xianyu/publish.js","lineNumber":40,"sourceCode":"    }\n    return buildPublishUrl();\n}\n\nfunction requireText(value, label) {\n    const text = String(value ?? '').replace(/\\s+/g, ' ').trim();\n    if (!text) {\n        throw new ArgumentError(`xianyu publish ${label} cannot be empty`);\n    }\n    return text;\n}\n\nfunction parsePositivePrice(value, label) {\n    if (value == null || String(value).trim() === '') {\n        return null;\n    }\n    const text = String(value).trim();\n    if (!/^\\d+(?:\\.\\d{1,2})?$/.test(text)) {\n        throw new ArgumentError(`xianyu publish ${label} must be a positive price with at most 2 decimals`);\n    }\n    const price = Number(text);\n    if (!Number.isFinite(price) || price <= 0) {\n        throw new ArgumentError(`xianyu publish ${label} must be a positive price`);\n    }\n    return text;\n}\n\nfunction validateCondition(value) {\n    const condition = requireText(value, 'condition');\n    if (!CONDITION_CHOICES.includes(condition)) {\n        throw new ArgumentError(`xianyu publish condition must be one of: ${CONDITION_CHOICES.join(', ')}`);\n    }\n    return condition;\n}\n\nfunction validateImagePaths(raw) {\n    if (!raw) return [];","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xianyu/publish.js#L22-L58","documentation":"parsePositivePrice() validates an optional price string for `xianyu publish`. If a non-empty price is given that doesn't match /^\\d+(?:\\.\\d{1,2})?$/ (positive decimal with at most 2 fraction digits), ArgumentError `xianyu publish ${label} must be a positive price with at most 2 decimals` is thrown at clis/xianyu/publish.js:40. This enforces Goofish's price format up front.","triggerScenarios":"Passing prices like '12,50' (comma decimal), '¥100' or '$5' (currency symbols), '-3' (negative), '12.999' (3 decimals), '1e3' (scientific), or ' 12 ' variants that fail the strict regex. Null/empty passes through as null (no price).","commonSituations":"Parsing prices from scraped text or spreadsheets that include currency symbols or thousand separators; locales using comma as decimal separator; user input passed straight through without normalization; storing prices as floats formatted with extra precision.","solutions":["Normalize the price before calling: strip currency symbols, replace ',' with '.', and format to at most 2 decimals (e.g. parseFloat(...).toFixed(2)).","Remove thousand separators/commas that aren't decimal markers.","Ensure the value is positive; omit the field (null/'') entirely if no price should be set.","Add a regex pre-check /^^?\\d+(\\.\\d{1,2})?$/ in your caller with a friendly error."],"exampleFix":"// before\nawait publish({ title, price: rawPrice }); // rawPrice = '¥1,299.00' → ArgumentError\n\n// after\nconst price = rawPrice == null ? null : parseFloat(String(rawPrice).replace(/[^\\d.]/g, '')).toFixed(2);\nawait publish({ title, price });","handlingStrategy":"validation","validationCode":"const PRICE_RE = /^\\d+(?:\\.\\d{1,2})?$/;\nif (price != null && String(price).trim() !== '' && !PRICE_RE.test(String(price).trim())) {\n  throw new Error(`price must match d+.dd (got ${price})`);\n}","typeGuard":"function isValidPrice(v) { return v == null || String(v).trim() === '' || /^\\d+(?:\\.\\d{1,2})?$/.test(String(v).trim()); }","tryCatchPattern":"try {\n  await publish({ title, price });\n} catch (e) {\n  if (e instanceof ArgumentError && /positive price/.test(e.message)) {\n    price = parseFloat(String(price).replace(/[^\\d.]/g, '')).toFixed(2); // normalize and retry once\n    return publish({ title, price });\n  }\n  throw e;\n}","preventionTips":["Strip currency symbols and thousand separators before passing prices.","Convert locale comma decimals (12,50) to dot format (12.50).","Round/format to at most 2 decimal places.","Omit the price field entirely (null) when no price should be set — empty string is allowed and means 'no price'."],"tags":["argument-validation","xianyu","input-validation","price-format"],"backgroundTag":"invalid-number-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}