jackwener/OpenCLI · error · ArgumentError
Pinterest usernames have no "@": "${raw}"
Error message
Pinterest usernames have no "@": "${raw}" What it means
Pinterest usernames do not use '@' prefixes (unlike Twitter/Instagram handles). parseUsername detects a leading '@' after normalization and throws this ArgumentError telling you to drop it. This prevents sending '@janedoe' to the API where it would fail as an unknown user.
Source
Thrown at clis/pinterest/utils.js:112
let value = String(raw ?? '').trim();
if (!value) throw new ArgumentError('username is required', 'Pass a Pinterest username or profile URL, e.g. janedoe');
if (/^https?:\/\//i.test(value)) {
try {
value = decodeSegment(new URL(value).pathname.split('/').filter(Boolean)[0] || '');
} catch {
throw new ArgumentError(`Invalid profile URL: ${raw}`, 'Use a full profile URL like https://www.pinterest.com/janedoe/');
}
}
value = value.replace(/^\/+|\/+$/g, '');
if (!value) throw new ArgumentError(`Not a username: "${raw}"`, 'Pass the bare username, e.g. janedoe');
if (value.includes('/')) {
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']) {View on GitHub (pinned to 49907e53dc)
Solutions
- Remove the '@' and pass the bare username, e.g. janedoe
- Normalize in your code: value.replace(/^@+/, '') before calling
- Update cross-posted config/templates to store plain usernames
- Search your config for '@' prefixes on Pinterest credentials
Example fix
// before
const user = parseUsername('@janedoe');
// after
const user = parseUsername('@janedoe'.replace(/^@+/, '')); // 'janedoe' Defensive patterns
Strategy: validation
Validate before calling
const cleaned = String(input || '').trim().replace(/^@+/, '');
if (cleaned !== input) console.warn('stripped @ from username'); Type guard
const isHandleFree = (v) => typeof v === 'string' && !v.startsWith('@'); Try / catch
try {
username = parseUsername(input);
} catch (err) {
if (err instanceof ArgumentError && err.message.includes('"@"')) {
username = parseUsername(input.replace(/^@+/, ''));
} else throw err;
} Prevention
- Strip leading '@' at every ingestion point (CLI, config, webhooks)
- When porting scripts from Twitter/Instagram, audit handle formatting
- Store Pinterest identities as plain lowercase usernames
- Add a lint/config check rejecting '@' in username fields
When it happens
Trigger: Calling parseUsername('@janedoe') or a URL-like '@janedoe/...' — the stripped value starts with '@'.
Common situations: Migrating scripts from a Twitter/Instagram integration that used @handles; users typing the handle as displayed in the Pinterest UI; config copied from another service's docs.
Related errors
- username is required
- Not a username: "${raw}"
- archive search sort must be one of ${SORT_OPTIONS.join(', ')
- archive search mediatype must be one of ${MEDIATYPES.join(',
- archive search limit must be a positive integer
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/9413022053cd379f.
Report an issue: GitHub.