jackwener/OpenCLI · error · ArgumentError
shot URL must use dribbble.com
Error message
shot URL must use dribbble.com
What it means
After a shot value parses as a URL, requireShotTarget checks that the hostname is dribbble.com or a subdomain of it. This ArgumentError is thrown when a valid URL points at a different host, because the library only scrapes dribbble.com shot pages.
Source
Thrown at clis/dribbble/utils.js:60
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}` : '';
throw new CommandExecutionError(`${command} selector drift${reason}`);
}
if (!Array.isArray(payload.rows)) {View on GitHub (pinned to 49907e53dc)
Solutions
- Use the canonical https://dribbble.com/shots/<id> URL.
- Extract the numeric id from wherever the link came from and pass the id instead of the URL.
- Check for typos in the hostname and ensure redirects are resolved to dribbble.com before passing the URL.
Example fix
// before
cli.shot({ shot: 'https://www.behance.net/gallery/123456/Shot' })
// after
cli.shot({ shot: 'https://dribbble.com/shots/123456' }); // or just 123456 Defensive patterns
Strategy: validation
Validate before calling
const url = new URL(shot);
if (!/(^|\.)dribbble\.com$/i.test(url.hostname)) {
throw new Error(`shot URL must point at dribbble.com, got ${url.hostname}`);
} Type guard
function isDribbbleUrl(v) {
try { return /(^|\.)dribbble\.com$/i.test(new URL(String(v)).hostname); } catch { return false; }
} Try / catch
try {
const result = command({ shot });
} catch (e) {
if (e instanceof ArgumentError && /shot URL must use dribbble\.com/.test(e.message)) {
console.error('Only dribbble.com shot URLs are supported; extract the id and pass that instead');
return;
}
throw e;
} Prevention
- Store canonical dribbble.com shot URLs in your data, not links from other sites.
- Resolve short links/redirects before passing them if you cannot guarantee the host.
- Check hostnames for typos (dribbble.org, dribble.com) in stored data.
When it happens
Trigger: Passing URLs from other sites (e.g. 'https://www.behance.net/gallery/123', 'https://example.com/shots/123') or mirror/proxied hosts that are not dribbble.com or *.dribbble.com.
Common situations: Mixing up shot links from other design sites stored in the same dataset, using a shortened link (bit.ly etc.) that resolves to a non-dribbble host string, or a typo like 'dribbble.org'.
Related errors
- <train-no> must not be empty
- <train-no> "${trainNo}" does not look like a 12306 internal
- --from station must not be empty
- --to station must not be empty
- --seat-types must contain only 12306 seat letters/digits (A-
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/6edcda0eeb272958.
Report an issue: GitHub.