{"record":{"id":"9413022053cd379f","repo":"jackwener/OpenCLI","slug":"pinterest-usernames-have-no-raw","errorCode":null,"errorMessage":"Pinterest usernames have no \"@\": \"${raw}\"","messagePattern":"Pinterest usernames have no \"@\": \"(.+?)\"","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/pinterest/utils.js","lineNumber":112,"sourceCode":"  let value = String(raw ?? '').trim();\n  if (!value) throw new ArgumentError('username is required', 'Pass a Pinterest username or profile URL, e.g. janedoe');\n  if (/^https?:\\/\\//i.test(value)) {\n    try {\n      value = decodeSegment(new URL(value).pathname.split('/').filter(Boolean)[0] || '');\n    } catch {\n      throw new ArgumentError(`Invalid profile URL: ${raw}`, 'Use a full profile URL like https://www.pinterest.com/janedoe/');\n    }\n  }\n  value = value.replace(/^\\/+|\\/+$/g, '');\n  if (!value) throw new ArgumentError(`Not a username: \"${raw}\"`, 'Pass the bare username, e.g. janedoe');\n  if (value.includes('/')) {\n    throw new ArgumentError(\n      `Not a username: \"${raw}\"`,\n      'This looks like a board or pin reference — pass just the username, e.g. janedoe',\n    );\n  }\n  if (value.startsWith('@')) {\n    throw new ArgumentError(`Pinterest usernames have no \"@\": \"${raw}\"`, 'Drop the @ and use the bare username, e.g. janedoe');\n  }\n  return value;\n}\n\n/** Parse a bare pin id or a /pin/<id>/ URL. */\nexport function parsePinId(raw) {\n  const value = String(raw ?? '').trim();\n  if (!value) throw new ArgumentError('pin id is required', 'Pass a pin id or /pin/<id>/ URL, e.g. 1234567890123456');\n  if (/^\\d+$/.test(value)) return value;\n  const match = value.match(/\\/pin\\/(\\d+)/);\n  if (match) return match[1];\n  throw new ArgumentError(`Not a pin id or pin URL: \"${raw}\"`, 'Expected a numeric id or a /pin/<id>/ URL, e.g. 1234567890123456');\n}\n\n/** Highest-resolution image URL available for a pin. */\nexport function pickPinImage(images) {\n  if (!images || typeof images !== 'object') return '';\n  for (const key of ['orig', '736x', '564x', '474x', '236x']) {","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pinterest/utils.js#L94-L130","documentation":"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.","triggerScenarios":"Calling parseUsername('@janedoe') or a URL-like '@janedoe/...' — the stripped value starts with '@'.","commonSituations":"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.","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"],"exampleFix":"// before\nconst user = parseUsername('@janedoe');\n// after\nconst user = parseUsername('@janedoe'.replace(/^@+/, '')); // 'janedoe'","handlingStrategy":"validation","validationCode":"const cleaned = String(input || '').trim().replace(/^@+/, '');\nif (cleaned !== input) console.warn('stripped @ from username');","typeGuard":"const isHandleFree = (v) => typeof v === 'string' && !v.startsWith('@');","tryCatchPattern":"try {\n  username = parseUsername(input);\n} catch (err) {\n  if (err instanceof ArgumentError && err.message.includes('\"@\"')) {\n    username = parseUsername(input.replace(/^@+/, ''));\n  } else throw err;\n}","preventionTips":["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"],"tags":["validation","argument-error","username","format-mismatch"],"backgroundTag":"invalid-username-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}