jackwener/OpenCLI · error · Error

Invalid component identifier: ${raw}. Expected author/slug.

Error message

Invalid component identifier: ${raw}. Expected author/slug.

What it means

Thrown by parseComponentInput after the input splits into exactly two segments but one of them is empty (falsy). Since empty segments are filtered out earlier this usually indicates a slug or username made only of whitespace-stripped content after trimPathSegment, or an input like 'author/' where path trimming leaves a single empty piece — a defensive check for a malformed author/slug pair.

Source

Thrown at clis/uiverse/_shared.js:38

  let pathname = raw;
  if (/^https?:\/\//i.test(raw)) {
    const url = new URL(raw);
    if (url.hostname !== 'uiverse.io' && url.hostname !== 'www.uiverse.io') {
      throw new Error(`Unsupported non-Uiverse URL: ${raw}`);
    }
    pathname = url.pathname;
  }

  const cleaned = trimPathSegment(pathname);
  const segments = cleaned.split('/').filter(Boolean);
  if (segments.length !== 2) {
    throw new Error(`Could not parse author/slug from input: ${raw}`);
  }

  const [username, slug] = segments;
  if (!username || !slug) {
    throw new Error(`Invalid component identifier: ${raw}. Expected author/slug.`);
  }

  return {
    raw,
    username,
    slug,
    url: `${UIVERSE_BASE_URL}/${username}/${slug}`,
  };
}

async function fetchJsonInBrowser(page, url) {
  const raw = await page.evaluate(`(async () => {
    const url = ${JSON.stringify(url)};
    const response = await fetch(url, {
      credentials: 'include',
      headers: {
        accept: 'application/json, text/plain, */*',
      },

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Ensure both author and slug are non-empty, e.g. 'pravsingh/sky-button'
  2. Check upstream variables feeding the identifier (log them before calling the CLI)
  3. Copy the identifier directly from the component page URL instead of constructing it
  4. Sanitize source data: replace blank slugs with the real component slug

Example fix

// before
await getPostDetails(page, `${author}/`); // slug empty -> 'Invalid component identifier'
// after
if (!author || !slug) throw new Error('author and slug are both required');
await getPostDetails(page, `${author}/${slug}`);
Defensive patterns

Strategy: validation

Validate before calling

function assertCompleteIdentifier([username, slug]) {
  if (!username?.trim() || !slug?.trim()) throw new Error('both author and slug are required');
}
const segs = input.split('/').filter(Boolean);
assertCompleteIdentifier(segs);

Type guard

const isCompletePair = (v) =>
  typeof v === 'string' && v.split('/').filter(s => s.trim()).length === 2;

Try / catch

try {
  const details = await getPostDetails(page, input);
} catch (e) {
  if (e.message.startsWith('Invalid component identifier')) {
    console.error(`Malformed identifier '${input}' — check for empty author or slug.`);
    process.exit(2);
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing inputs like ' / ' or strings whose trimmed segments collapse to empty; a URL whose pathname segments are whitespace or control characters that trim away; programmatically constructed identifiers where username or slug variable was empty string and joined as '/' or 'a/'.

Common situations: Template strings like `${author}/${slug}` with an undefined/empty slug; stripping invalid characters from a slug down to empty string before passing it in; spreadsheet/config data with blank slug column.

Related errors


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