jackwener/OpenCLI · error · ArgumentError

shop_id must be a non-empty string

Error message

shop_id must be a non-empty string

What it means

normalizeShopId accepts either a bare shop id or a dianping shop URL (/shop/<id>) and extracts the id. This specific error is thrown when the input is empty or falsy after string coercion — e.g. null, undefined, '', or a placeholder that trims to nothing — since no id can be derived. Note that a non-empty input failing the id pattern check throws a different error ('does not look like a dianping shop id').

Source

Thrown at clis/dianping/utils.js:78

            'city',
            `unknown city '${cityArg}'. pass a numeric cityId or one of: ${names}`,
        );
    }
    return id;
}

export function requireSearchLimit(value) {
    const raw = value == null || value === '' ? 15 : value;
    const limit = typeof raw === 'number' ? raw : Number(String(raw).trim());
    if (!Number.isInteger(limit) || limit < 1 || limit > 15) {
        throw new ArgumentError('limit must be an integer between 1 and 15 (dianping single page)');
    }
    return limit;
}

export function normalizeShopId(rawInput) {
    const raw = String(rawInput || '').trim();
    if (!raw) throw new ArgumentError('shop_id must be a non-empty string');

    const idMatch = raw.match(/\/shop\/([^?#/]+)/);
    const shopId = idMatch ? idMatch[1] : raw;
    if (!/^[A-Za-z0-9_-]+$/.test(shopId)) {
        throw new ArgumentError(`'${raw}' does not look like a dianping shop id`);
    }
    return shopId;
}

export function wrapDianpingStep(label, fn) {
    return Promise.resolve()
        .then(fn)
        .catch((err) => {
            if (err?.code) throw err;
            const message = err?.message || String(err);
            throw new CommandExecutionError(`dianping ${label} failed: ${message}`);
        });
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a real dianping shop id (e.g. from search results' shop_id column) or a full shop URL like https://www.dianping.com/shop/1234567.
  2. Verify the upstream step actually produced an id — re-run the search and confirm the shop_id field is populated before chaining.
  3. Guard the call: if (!shopId || !shopId.trim()) fail early with a clear message instead of invoking the command.
  4. Check shell/config plumbing — quoting, exported variables, and non-empty CSV/JSON fields.

Example fix

// before
const id = row.shop_id; // '' when search returned junk
await shop(id); // ArgumentError: shop_id must be a non-empty string
// after
if (!row?.shop_id?.trim()) throw new Error('upstream search returned no shop_id');
await shop(row.shop_id.trim());
Defensive patterns

Strategy: validation

Validate before calling

function hasUsableShopId(v) {
  const raw = String(v ?? '').trim();
  if (!raw) return false;
  const m = raw.match(/\/shop\/([^?#/]+)/);
  const id = m ? m[1] : raw;
  return /^[A-Za-z0-9_-]+$/.test(id);
}

Type guard

function isShopIdInput(v) {
  return typeof v === 'string' && v.trim().length > 0;
}

Try / catch

try {
  const id = normalizeShopId(input);
} catch (e) {
  if (e.name === 'ArgumentError' && /non-empty string/.test(e.message)) {
    console.error('No shop id provided — check upstream search output / flag plumbing');
  } else if (e.name === 'ArgumentError') {
    console.error(`'${input}' is not a shop id or /shop/ URL`);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the shop command with shop_id='' or whitespace only; passing an unset variable (undefined/null) from a script; piping an empty lookup result from a prior step into shop_id; a template string that interpolates to ''.

Common situations: Chained automation where a previous search returned no rows so the id variable is empty; shell variable not exported/quoted; reading an empty CSV/JSON field; forgetting to pass the --shop-id flag and an empty default being used.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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