jackwener/OpenCLI · error · ArgumentError

Invalid profile URL: ${raw}

Error message

Invalid profile URL: ${raw}

What it means

When parseUsername receives a string that starts with http(s)://, it tries to parse it as a profile URL and extract the first path segment. If the URL constructor throws, this ArgumentError is raised with guidance to use a full profile URL. It distinguishes 'malformed URL' from 'not a username' so the fix message is precise.

Source

Thrown at clis/pinterest/utils.js:100

    throw new ArgumentError(
      `"${raw}" is a Pinterest /${username}/ URL, not a board`,
      username.toLowerCase() === 'pin'
        ? 'Pass the board this pin lives on, e.g. janedoe/my-board (`opencli pinterest pin <id>` reports it)'
        : 'Pass <username>/<slug>, a board URL, or a numeric board id',
    );
  }
  return { username, slug, path: `/${username}/${slug}/` };
}

/** Normalize a username or profile URL to a bare username (Pinterest has no @-handles). */
export function parseUsername(raw) {
  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) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a full, well-formed profile URL like https://www.pinterest.com/janedoe/
  2. Or simply pass the bare username janedoe — no URL needed
  3. Quote the URL in your shell so special characters survive
  4. Check for whitespace/smart quotes and clean the string before calling

Example fix

// before
const user = parseUsername('https://pinterest com/janedoe/');
// after
const user = parseUsername('https://www.pinterest.com/janedoe/'); // or just 'janedoe'
Defensive patterns

Strategy: validation

Validate before calling

function isCleanProfileUrl(s) {
  if (!/^https?:\/\//i.test(s || '')) return true;
  try { new URL(s.trim()); return true; } catch { return false; }
}
if (!isCleanProfileUrl(input)) input = input.trim().replace(/[\s\u2018\u2019]/g, '');

Type guard

const isUrl = (v) => { try { new URL(v); return true; } catch { return false; } };

Try / catch

try {
  username = parseUsername(input);
} catch (err) {
  if (err instanceof ArgumentError && err.message.startsWith('Invalid profile URL')) {
    console.error(`${err.message} — ${err.hint}`);
    process.exitCode = 2;
  } else throw err;
}

Prevention

When it happens

Trigger: Passing an unparseable http(s) string such as 'https://pinterest com/janedoe' (space), 'https://', or a URL mangled by shell quoting to parseUsername.

Common situations: URL broken by an unescaped '&' or spaces in a shell command; pasted URL containing smart quotes; template placeholder never substituted ('${PROFILE_URL}'); truncated URL from a log line.

Related errors


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