jackwener/OpenCLI · error · ArgumentError
Not a pin id or pin URL: "${raw}"
Error message
Not a pin id or pin URL: "${raw}" What it means
parsePinId validates that its argument is either a numeric Pinterest pin id or a /pin/<id>/ URL. It throws ArgumentError when the value is non-empty but matches neither pattern, because downstream Pinterest resource calls require a real pin id.
Source
Thrown at clis/pinterest/utils.js:124
throw new ArgumentError(
`Not a username: "${raw}"`,
'This looks like a board or pin reference — pass just the username, e.g. janedoe',
);
}
if (value.startsWith('@')) {
throw new ArgumentError(`Pinterest usernames have no "@": "${raw}"`, 'Drop the @ and use the bare username, e.g. janedoe');
}
return value;
}
/** Parse a bare pin id or a /pin/<id>/ URL. */
export function parsePinId(raw) {
const value = String(raw ?? '').trim();
if (!value) throw new ArgumentError('pin id is required', 'Pass a pin id or /pin/<id>/ URL, e.g. 1234567890123456');
if (/^\d+$/.test(value)) return value;
const match = value.match(/\/pin\/(\d+)/);
if (match) return match[1];
throw new ArgumentError(`Not a pin id or pin URL: "${raw}"`, 'Expected a numeric id or a /pin/<id>/ URL, e.g. 1234567890123456');
}
/** Highest-resolution image URL available for a pin. */
export function pickPinImage(images) {
if (!images || typeof images !== 'object') return '';
for (const key of ['orig', '736x', '564x', '474x', '236x']) {
const candidate = images[key];
if (candidate && candidate.url) return candidate.url;
}
return '';
}
/** Map a raw pin to the shared grid-row shape used by list commands. */
export function toPinRow(pin) {
const id = String(pin.id ?? '');
return {
pinId: id,
title: (pin.title || pin.grid_title || '').trim(),View on GitHub (pinned to 49907e53dc)
Solutions
- Pass the numeric pin id, e.g. 1234567890123456
- Pass the full /pin/<id>/ URL copied from the browser address bar
- If you have a pin object, extract its id field before calling
- Trim whitespace and strip query strings from the URL before passing
Example fix
// before
await cmd.id('my summer mood board pin');
// after
await cmd.id('https://www.pinterest.com/pin/1234567890123456/'); Defensive patterns
Strategy: validation
Validate before calling
function isValidPinRef(v){const s=String(v??'').trim();return /^\d+$/.test(s)||/\/pin\/(\d+)/.test(s);} Type guard
function isPinId(v){return typeof v==='string'&&/^\d+$/.test(v.trim());} Try / catch
try { const pinId = await cmd.id(rawPin); } catch (e) { if (e instanceof ArgumentError) console.error(`Bad pin ref: ${rawPin}`); else throw e; } Prevention
- Always extract the id field from pin objects instead of passing titles
- Copy pin URLs directly from the address bar including /pin/<id>/
- Validate with a numeric regex before calling
- Strip query strings and trim whitespace from URLs
When it happens
Trigger: Calling id(pin) or sourcePinId(pin) with a display name, a slug like 'my-cool-pin', a full pin URL without a numeric id (e.g. https://pinterest.com/pin/ with the id stripped), a URL-encoded or whitespace-padded garbage string, or passing a pin object/string instead of an id.
Common situations: Copy-pasting a pin title or description instead of the id; extracting the URL with a regex that dropped the numeric path segment; passing a board pin item's 'title' field rather than its 'id'; localization suffixes in URLs; users typing 'pin/12345' without leading slash so the /pin/ regex doesn't match... (note 'pin/12345' actually fails because the regex requires '/pin/').
Related errors
- Not a board reference: "${trimmed}"
- ${raw}' does not look like a dianping shop id
- flomo memos --${name} must be a positive integer
- board is required
- ${name} must be${suffix} (got "${raw}")
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/d27fd555597c4160.
Report an issue: GitHub.