{"record":{"id":"eed3df0199eccc15","repo":"jackwener/OpenCLI","slug":"could-not-parse-author-slug-from-input-raw","errorCode":null,"errorMessage":"Could not parse author/slug from input: ${raw}","messagePattern":"Could not parse author/slug from input: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/uiverse/_shared.js","lineNumber":33,"sourceCode":"export function parseComponentInput(input) {\n  const raw = String(input || '').trim();\n  if (!raw) {\n    throw new Error('Missing component input. Pass a full Uiverse URL or an author/slug identifier.');\n  }\n\n  let pathname = raw;\n  if (/^https?:\\/\\//i.test(raw)) {\n    const url = new URL(raw);\n    if (url.hostname !== 'uiverse.io' && url.hostname !== 'www.uiverse.io') {\n      throw new Error(`Unsupported non-Uiverse URL: ${raw}`);\n    }\n    pathname = url.pathname;\n  }\n\n  const cleaned = trimPathSegment(pathname);\n  const segments = cleaned.split('/').filter(Boolean);\n  if (segments.length !== 2) {\n    throw new Error(`Could not parse author/slug from input: ${raw}`);\n  }\n\n  const [username, slug] = segments;\n  if (!username || !slug) {\n    throw new Error(`Invalid component identifier: ${raw}. Expected author/slug.`);\n  }\n\n  return {\n    raw,\n    username,\n    slug,\n    url: `${UIVERSE_BASE_URL}/${username}/${slug}`,\n  };\n}\n\nasync function fetchJsonInBrowser(page, url) {\n  const raw = await page.evaluate(`(async () => {\n    const url = ${JSON.stringify(url)};","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/uiverse/_shared.js#L15-L51","documentation":"Thrown by parseComponentInput when the input (or the pathname of a valid uiverse.io URL) does not resolve to exactly two path segments. The library strictly expects an author/slug pair; 1 segment (just an author), 3+ segments (extra path like /element/button/slug), or 0 segments all fail.","triggerScenarios":"Passing just the author name ('pravsingh'); passing a full URL with extra path segments (https://uiverse.io/a/b/c); passing a uiverse.io explore/element/category URL instead of a component page URL; passing a URL with query string only or a bare domain (pathname '/' -> 0 segments).","commonSituations":"Grabbing the wrong link off uiverse.io (an element category page like /element/checkbox instead of a component page); truncating a URL; building URLs programmatically and joining an extra segment; forgetting the slug portion of an author/slug pair.","solutions":["Provide exactly author/slug, e.g. 'pravsingh/sky-button'","Use the component's canonical page URL https://uiverse.io/<author>/<slug>, not category or element pages","Strip extra path segments or trailing slashes/query strings from a copied URL","If you only know the author, browse their profile to pick a specific component slug"],"exampleFix":"// before\nawait getPostDetails(page, 'https://uiverse.io/element/checkbox'); // 2 segments but not author/slug context, or 'pravsingh' -> 1 segment\n// after\nawait getPostDetails(page, 'https://uiverse.io/pravsingh/sky-button');","handlingStrategy":"validation","validationCode":"function assertAuthorSlug(input) {\n  const path = input.startsWith('http') ? new URL(input).pathname : input;\n  const segs = path.split('/').filter(Boolean);\n  if (segs.length !== 2) throw new Error(`expected author/slug, got: ${input}`);\n}\nassertAuthorSlug(input);","typeGuard":"const isAuthorSlug = (input) => {\n  const path = /^https?:\\/\\//i.test(input) ? new URL(input).pathname : input;\n  return path.split('/').filter(Boolean).length === 2;\n};","tryCatchPattern":"try {\n  const details = await getPostDetails(page, input);\n} catch (e) {\n  if (e.message.startsWith('Could not parse author/slug')) {\n    console.error(`Bad identifier '${input}'. Use uiverse.io/<author>/<slug>.`);\n    process.exit(2);\n  }\n  throw e;\n}","preventionTips":["Always use the canonical component page URL, not element/category/profile pages","Strip query strings, hashes, and trailing slashes from copied URLs","When constructing identifiers programmatically, assert both parts are non-empty","Keep a lookup of known-good author/slug pairs in scripts"],"tags":["input-validation","url-parsing","argument-parsing"],"backgroundTag":"invalid-identifier-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}