jackwener/OpenCLI · error · ArgumentError
xianyu search min-price cannot be greater than max-price
Error message
xianyu search min-price cannot be greater than max-price
What it means
After both price bounds are parsed, the CLI checks that min-price <= max-price. A reversed range cannot be sent to Goofish's server-side price filter (priceRange:<min>,<max>;), so an ArgumentError is thrown listing both received values.
Source
Thrown at clis/xianyu/search.js:214
strategy: Strategy.COOKIE,
navigateBefore: false,
browser: true,
args: [
{ name: 'query', required: true, positional: true, help: '搜索关键词' },
{ name: 'limit', type: 'int', default: 20, help: `返回结果数(最多 ${MAX_LIMIT},自动翻页)` },
{ name: 'min-price', type: 'float', help: '最低价格(元),服务端筛选' },
{ name: 'max-price', type: 'float', help: '最高价格(元),服务端筛选' },
{ name: 'province', type: 'string', help: '省份名(如 广东),服务端按地区筛选' },
{ name: 'city', type: 'string', help: '城市名(如 深圳 / 湛江),可单独使用,服务端按地区筛选' },
],
columns: ['item_id', 'rank', 'title', 'price', 'condition', 'brand', 'location', 'badge', 'want', 'url'],
func: async (page, kwargs) => {
const query = String(kwargs.query || '').trim();
const limit = normalizeLimit(kwargs.limit);
const minPrice = parsePriceArg(kwargs['min-price'], 'min-price');
const maxPrice = parsePriceArg(kwargs['max-price'], 'max-price');
if (minPrice != null && maxPrice != null && minPrice > maxPrice) {
throw new ArgumentError('xianyu search min-price cannot be greater than max-price', `Received --min-price ${minPrice} and --max-price ${maxPrice}`);
}
const province = String(kwargs.province || '').trim();
const city = String(kwargs.city || '').trim();
const searchFilter = buildSearchFilter(minPrice, maxPrice);
const extraFilterValue = buildExtraFilterValue(province, city);
const fromFilter = Boolean(searchFilter) || extraFilterValue !== '{}';
await page.goto(buildSearchUrl(query));
await page.wait(2);
const result = await page.evaluate(buildSearchEvaluate({ keyword: query, searchFilter, extraFilterValue, fromFilter, maxItems: limit }));
if (result?.error === 'auth-required') {
throw new AuthRequiredError('www.goofish.com', 'Xianyu search requires a logged-in browser session');
}
if (result?.error === 'blocked') {
throw new CommandExecutionError('Xianyu returned a verification page or blocked the current browser session');
}
if (result?.error === 'mtop-not-ready') {
throw selectorError('window.lib.mtop', '闲鱼页面未完成初始化,无法调用搜索接口');
}View on GitHub (pinned to 49907e53dc)
Solutions
- Swap the values: --min-price 1000 --max-price 5000
- Omit one bound to do a single-sided range (e.g. only --max-price 5000)
- Verify the order of variables producing the two flags in scripts
Example fix
// before xianyu search 'mechanical keyboard' --min-price 800 --max-price 300 // after xianyu search 'mechanical keyboard' --min-price 300 --max-price 800
Defensive patterns
Strategy: validation
Validate before calling
const min = Number(minPrice), max = Number(maxPrice);
if (Number.isFinite(min) && Number.isFinite(max) && min > max) throw new Error(`min-price ${min} > max-price ${max}`); Type guard
const isSaneRange = (min, max) => min == null || max == null || Number(min) <= Number(max);
Try / catch
try { await xianyuSearch({ 'min-price': min, 'max-price': max }); } catch (e) { if (e instanceof ArgumentError && /greater than max-price/.test(e.message)) { [min, max] = [max, min]; /* swap and retry */ } else throw e; } Prevention
- Sort min/max programmatically before passing them as flags
- When deriving bounds from variables, assert order with an invariant check
- Omit one bound when you only need a single-sided range
When it happens
Trigger: Running `xianyu search` with --min-price greater than --max-price, e.g. --min-price 5000 --max-price 1000.
Common situations: Swapping flag order mentally ('min 5000 max 1000' when intending a budget of 1000), or computing the bounds from variables where the values were reversed.
Related errors
- xianyu search ${label} must be a non-negative number
- <train-no> "${trainNo}" does not look like a 12306 internal
- --from station must not be empty
- --to station must not be empty
- --seat-types must contain only 12306 seat letters/digits (A-
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/71429f82baec5340.
Report an issue: GitHub.