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

  1. Pass a price greater than 0 with at most 2 decimals, e.g. price: '29.90'
  2. Add a caller-side check that Number(price) > 0 before invoking publish
  3. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/23f4e92275221845. Report an issue: GitHub.