jackwener/OpenCLI · error · ArgumentError
xianyu publish ${label} must be a positive price
Error message
xianyu publish ${label} must be a positive price What it means
parsePositivePrice validates the xianyu publish price and throws ArgumentError when the value, though formatted as a decimal string, is not strictly positive (e.g. zero) or not finite. The regex already limits input to digits with at most 2 decimals, so this branch fires when the numeric value fails the > 0 check. The library throws it to guarantee a real positive price before submitting the listing.
Source
Thrown at clis/xianyu/publish.js:44
function requireText(value, label) {
const text = String(value ?? '').replace(/\s+/g, ' ').trim();
if (!text) {
throw new ArgumentError(`xianyu publish ${label} cannot be empty`);
}
return text;
}
function parsePositivePrice(value, label) {
if (value == null || String(value).trim() === '') {
return null;
}
const text = String(value).trim();
if (!/^\d+(?:\.\d{1,2})?$/.test(text)) {
throw new ArgumentError(`xianyu publish ${label} must be a positive price with at most 2 decimals`);
}
const price = Number(text);
if (!Number.isFinite(price) || price <= 0) {
throw new ArgumentError(`xianyu publish ${label} must be a positive price`);
}
return text;
}
function validateCondition(value) {
const condition = requireText(value, 'condition');
if (!CONDITION_CHOICES.includes(condition)) {
throw new ArgumentError(`xianyu publish condition must be one of: ${CONDITION_CHOICES.join(', ')}`);
}
return condition;
}
function validateImagePaths(raw) {
if (!raw) return [];
const paths = String(raw).split(',').map((item) => item.trim()).filter(Boolean);
if (paths.length === 0) return [];
if (paths.length > MAX_IMAGES) {
throw new ArgumentError(`xianyu publish images supports at most ${MAX_IMAGES} files`);View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a price greater than 0 with at most 2 decimals, e.g. price: '29.90'
- Add a caller-side check that Number(price) > 0 before invoking publish
- If price is optional in your flow, omit it rather than passing '0'
Example fix
// before
await publish({ title: 'Phone', price: '0' });
// after
await publish({ title: 'Phone', price: '29.90' }); Defensive patterns
Strategy: validation
Validate before calling
function isValidPrice(p) {
return typeof p === 'string' && /^\d+(?:\.\d{1,2})?$/.test(p.trim()) && Number(p) > 0;
}
if (!isValidPrice(price)) throw new Error(`price must be > 0: got ${price}`); Type guard
function isPositivePrice(v) {
return typeof v === 'string' && /^\d+(?:\.\d{1,2})?$/.test(v.trim()) && Number(v) > 0;
} Try / catch
try {
await publish({ price });
} catch (e) {
if (e instanceof ArgumentError && /must be a positive price/.test(e.message)) {
console.error(`Bad price "${price}": use a number > 0 with max 2 decimals`);
} else throw e;
} Prevention
- Validate price with a regex + Number() > 0 check before calling publish
- Never pass 0 as a placeholder; omit optional fields instead
- Keep prices as strings from CLI/JSON to avoid float formatting surprises
When it happens
Trigger: Calling normalizePublishArgs (or the price helper) with kwargs.price = '0', '0.00', or '0.0' — passes the decimal regex but fails price <= 0.
Common situations: Placeholder price of 0 ('decide later'), templated scripts with unfilled price variables defaulting to 0, or spreadsheet imports where an empty price cell is coerced to '0'.
Related errors
- xianyu publish price cannot be empty
- archive search sort must be one of ${SORT_OPTIONS.join(', ')
- archive search mediatype must be one of ${MEDIATYPES.join(',
- archive search limit must be a positive integer
- archive search limit must be <= 100
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/23f4e92275221845.
Report an issue: GitHub.