jackwener/OpenCLI · error · ArgumentError
shot URL must match dribbble.com/shots/<id>
Error message
shot URL must match dribbble.com/shots/<id>
What it means
The URL host is valid dribbble.com, but the pathname does not match /shots/<numeric id>. requireShotTarget requires the path to start with /shots/ followed by digits (optionally followed by '-', '/', or end of path). This ArgumentError is thrown for dribbble.com pages that are not individual shot pages.
Source
Thrown at clis/dribbble/utils.js:63
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}` : '';
throw new CommandExecutionError(`${command} selector drift${reason}`);
}
if (!Array.isArray(payload.rows)) {
throw new CommandExecutionError(`${command} returned a malformed rows payload`);
}
if (payload.rows.length === 0) {View on GitHub (pinned to 49907e53dc)
Solutions
- Use a URL of the form https://dribbble.com/shots/<numeric id> (trailing slug like /shots/12345-Name is accepted).
- If you only have a profile or listing URL, first extract the specific shot id you need and pass that.
- Verify the id portion is numeric — alphabetic path segments fail the match.
Example fix
// before
cli.shot({ shot: 'https://dribbble.com/halolab' }) // profile, not a shot
// after
cli.shot({ shot: 'https://dribbble.com/shots/1234567-halolab-shot' }); Defensive patterns
Strategy: validation
Validate before calling
const url = new URL(shot);
const m = url.pathname.match(/^\/shots\/(\d+)(?:-|\/|$)/);
if (!m) throw new Error('shot URL must be dribbble.com/shots/<numeric id>'); Type guard
function isShotPageUrl(v) {
try { return /^\/shots\/(\d+)(?:-|\/|$)/.test(new URL(String(v)).pathname); } catch { return false; }
} Try / catch
try {
const result = command({ shot });
} catch (e) {
if (e instanceof ArgumentError && /shots\/<id>/.test(e.message)) {
console.error(`'${shot}' is a dribbble.com page but not a shot page; use /shots/<numeric id>`);
return;
}
throw e;
} Prevention
- Confirm the URL path starts with /shots/ followed by digits before calling.
- Don't confuse designer profile URLs (/ha-lolab style) with shot URLs.
- Extract the id with your own regex and pass the numeric id to avoid path-shape issues.
When it happens
Trigger: Passing URLs like 'https://dribbble.com/halolab' (profile page), 'https://dribbble.com/shots' (listing), 'https://dribbble.com/shots/abc' (non-numeric id), or a shot URL with extra segments the regex doesn't accept.
Common situations: Grabbing a designer profile URL when a shot was intended, copying a shots listing page, or saving a URL with a slug-less/typo'd id from bookmarks.
Related errors
- designer must be a Dribbble username or profile slug
- shot must be a numeric id or dribbble.com/shots URL
- flathub appId "${value}" is not a valid AppStream identifier
- hf paper id "${args.id}" is not a valid arXiv id
- weibo delete: id must be a numeric idstr, mblogid, or Weibo
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/5315394658803cdd.
Report an issue: GitHub.