jackwener/OpenCLI · error · ArgumentError

shot must be a numeric id or dribbble.com/shots URL

Error message

shot must be a numeric id or dribbble.com/shots URL

What it means

requireShotTarget first accepts pure numeric ids, then attempts to parse the value as a URL with the URL constructor. When parsing fails (no scheme, invalid characters, etc.) it throws this ArgumentError because the value is neither a numeric id nor a parseable URL.

Source

Thrown at clis/dribbble/utils.js:57

export function requireDesigner(value) {
    const designer = String(value ?? '').trim();
    if (!designer) throw new ArgumentError('designer is required (for example: halolab)');
    if (!/^[A-Za-z0-9_-]{1,100}$/.test(designer)) {
        throw new ArgumentError('designer must be a Dribbble username or profile slug');
    }
    return designer;
}

export function requireShotTarget(value) {
    const target = String(value ?? '').trim();
    if (!target) throw new ArgumentError('shot is required (numeric id or dribbble.com/shots URL)');
    if (/^\d+$/.test(target)) return target;

    let url;
    try {
        url = new URL(target);
    } catch {
        throw new ArgumentError('shot must be a numeric id or dribbble.com/shots URL');
    }
    if (!/(^|\.)dribbble\.com$/i.test(url.hostname)) {
        throw new ArgumentError('shot URL must use dribbble.com');
    }
    const match = url.pathname.match(/^\/shots\/(\d+)(?:-|\/|$)/);
    if (!match) throw new ArgumentError('shot URL must match dribbble.com/shots/<id>');
    return match[1];
}

export function requireRows(payload, command) {
    if (!payload || typeof payload !== 'object') {
        throw new CommandExecutionError(`${command} returned an unreadable browser payload`);
    }
    if (payload.empty) {
        throw new EmptyResultError(command, payload.reason || `${command} returned no results`);
    }
    if (!payload.ok) {
        const reason = payload.reason ? `: ${payload.reason}` : '';

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Include the full scheme when passing a URL: 'https://dribbble.com/shots/1234567'.
  2. Pass just the numeric id if you have it — it avoids URL parsing entirely.
  3. Pre-validate: if the value is not /^\d+$/, ensure it starts with http:// or https:// before calling.

Example fix

// before
cli.shot({ shot: 'dribbble.com/shots/1234567' }) // URL parse fails

// after
let shot = 'dribbble.com/shots/1234567';
if (!/^\d+$/.test(shot) && !/^https?:\/\//.test(shot)) shot = 'https://' + shot;
cli.shot({ shot });
Defensive patterns

Strategy: validation

Validate before calling

function normalizeShotTarget(v) {
  const s = String(v ?? '').trim();
  if (/^\d+$/.test(s)) return s;
  if (!/^https?:\/\//i.test(s)) return 'https://' + s.replace(/^\/+/, '');
  return s;
}

Type guard

function isNumericShotId(v) {
  return typeof v === 'string' && /^\d+$/.test(v.trim());
}

Try / catch

try {
  const result = command({ shot });
} catch (e) {
  if (e instanceof ArgumentError && /numeric id or dribbble\.com\/shots URL/.test(e.message)) {
    console.error(`'${shot}' is neither a numeric id nor a full URL; use https://dribbble.com/shots/<id>`);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing values like 'dribbble.com/shots/123' (no protocol), 'http://shot 123', 'shot/123456', or any free-form text that is not all digits and not an absolute URL.

Common situations: Copy-pasting a URL from a browser address bar but dropping the 'https://' prefix, users typing shorthand references, or CSV fields containing mixed id/URL values where some are malformed.

Related errors


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