{"record":{"id":"4ad9dcca0622ac40","repo":"jackwener/OpenCLI","slug":"xianyu-search-label-must-be-a-non-negative-numb","errorCode":null,"errorMessage":"xianyu search ${label} must be a non-negative number","messagePattern":"xianyu search (.+?) must be a non-negative number","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/xianyu/search.js","lineNumber":21,"sourceCode":"const ROWS_PER_PAGE = 30;\nconst MAX_LIMIT = 60;\nfunction normalizeLimit(value) {\n    const n = Number(value);\n    if (!Number.isFinite(n))\n        return 20;\n    return Math.min(MAX_LIMIT, Math.max(1, Math.floor(n)));\n}\nfunction buildSearchUrl(query) {\n    return `https://www.goofish.com/search?q=${encodeURIComponent(query)}`;\n}\n// Parse a --min-price / --max-price argument into a non-negative number, or null when omitted.\n// (`float` args are not auto-coerced by the framework, so they arrive as strings.)\nfunction parsePriceArg(value, label) {\n    if (value === undefined || value === null || value === '')\n        return null;\n    const n = Number(String(value).trim());\n    if (!Number.isFinite(n) || n < 0) {\n        throw new ArgumentError(`xianyu search ${label} must be a non-negative number`, `For example: --${label} 100000`);\n    }\n    return n;\n}\n// Goofish's PC search applies price filtering server-side via\n// propValueStr.searchFilter = \"priceRange:<min>,<max>;\" (values in 元). An omitted\n// bound is filled with a wide default so a single-sided range still works.\nfunction buildSearchFilter(minPrice, maxPrice) {\n    if (minPrice == null && maxPrice == null)\n        return '';\n    const lo = minPrice != null ? minPrice : 0;\n    const hi = maxPrice != null ? maxPrice : 99999999;\n    return `priceRange:${lo},${hi};`;\n}\n// Region filtering is server-side via extraFilterValue (a JSON string) carrying a\n// divisionList of {province, city} pairs. A city alone (empty province) is accepted,\n// as is a province alone (empty city). Returns \"{}\" when no region is requested.\nfunction buildExtraFilterValue(province, city) {\n    if (!province && !city)","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xianyu/search.js#L3-L39","documentation":"parsePriceArg validates the --min-price / --max-price options for `xianyu search`. Because float args arrive as strings, the value is trimmed and coerced with Number(); if the result is not a finite number or is negative, an ArgumentError is thrown. Prices must be non-negative numbers in 元 (yuan), since they are passed server-side as a priceRange search filter.","triggerScenarios":"Calling `xianyu search` with --min-price or --max-price set to a non-numeric string (e.g. 'abc', '1k', '100 元'), an empty-ish string, or a negative number like '-5'.","commonSituations":"Copying prices with currency symbols or thousand separators ('¥1,000'), typing '-100' by mistake, passing shell variables that are unset/empty, or assuming the CLI parses '1.5k'-style shorthand.","solutions":["Pass a plain non-negative number, e.g. --min-price 100000 --max-price 500000","Remove currency symbols, commas, and units from the value","Quote shell values containing special characters (e.g. '$100') so they are not mangled","Check that the variable feeding the flag is set and numeric before invoking"],"exampleFix":"// before\nxianyu search 'iphone' --min-price ¥1,000 --max-price -1\n// after\nxianyu search 'iphone' --min-price 1000 --max-price 999999","handlingStrategy":"validation","validationCode":"function isValidPrice(v){ if(v===undefined||v===null||v==='') return true; const n=Number(String(v).trim()); return Number.isFinite(n)&&n>=0; }\nif(!isValidPrice(minPrice)) throw new Error('min-price must be a non-negative number');","typeGuard":"const isPriceArg = (v) => v === undefined || v === null || v === '' || (Number.isFinite(Number(String(v).trim())) && Number(String(v).trim()) >= 0);","tryCatchPattern":"try { await xianyuSearch({ 'min-price': minPrice, 'max-price': maxPrice }); } catch (e) { if (e instanceof ArgumentError && /must be a non-negative number/.test(e.message)) { console.error('Fix the price flag: use a plain non-negative number'); } else throw e; }","preventionTips":["Sanitize user-supplied prices: strip currency symbols, commas, and units before invoking","Coerce and validate prices at the edge of your script, not inside the CLI call","Never pass negative or empty strings for price flags"],"tags":["argument-validation","cli","price-filter"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}