jackwener/OpenCLI · error · CommandExecutionError

github-trending parser drift: invalid repository identity "$

Error message

github-trending parser drift: invalid repository identity "${repo}"

What it means

After extracting the owner/repo path from a trending row's link, the parser validates it against `^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$`. If the extracted value doesn't look like a valid owner/repo pair, it throws this CommandExecutionError — an integrity check that the regex didn't capture garbage (e.g. a non-repository link) after markup changes.

Source

Thrown at clis/github-trending/repos.js:69

    const blocks = Array.from(String(html ?? '').matchAll(/<article\b[^>]*class="[^"]*\bBox-row\b[^"]*"[^>]*>([\s\S]*?)<\/article>/g))
        .map((match) => match[1]);
    const rows = [];

    if (blocks.length === 0) {
        if (hasExplicitEmptyTrending(html)) return rows;
        throw new CommandExecutionError('github-trending parser drift: no repository rows found');
    }

    for (const raw of blocks) {
        const block = raw;

        const nameMatch = block.match(/<h2\b[\s\S]*?href="\/([^"/?#]+\/[^"/?#]+)"/);
        if (!nameMatch) {
            throw new CommandExecutionError('github-trending parser drift: missing repository link');
        }
        const repo = decodeHtmlEntities(nameMatch[1]).trim();
        if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repo)) {
            throw new CommandExecutionError(`github-trending parser drift: invalid repository identity "${repo}"`);
        }

        const descMatch = block.match(/<p class="col-9 color-fg-muted[^"]*">([\s\S]*?)<\/p>/);
        const description = descMatch
            ? decodeHtmlEntities(stripTags(descMatch[1]).replace(/\s+/g, ' ')).trim()
            : '';

        const langMatch = block.match(/<span itemprop="programmingLanguage">([\s\S]*?)<\/span>/);
        const language = langMatch ? decodeHtmlEntities(stripTags(langMatch[1])).trim() : null;

        const escapedRepo = escapeRegExp(repo);
        const starsMatch = block.match(new RegExp(`<a\\b[^>]*href="/${escapedRepo}/stargazers"[^>]*>([\\s\\S]*?)</a>`));
        const forksMatch = block.match(new RegExp(`<a\\b[^>]*href="/${escapedRepo}/forks"[^>]*>([\\s\\S]*?)</a>`));
        const sinceMatch = block.match(/([\d,]+)\s+stars\s+(?:today|this week|this month)/i);

        rows.push({
            repo,
            description,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Upgrade the scraper package for updated regexes matching current markup
  2. Check the captured value in the message to see what the regex matched and adjust the pattern
  3. Retry later if GitHub is mid-deploy

Example fix

// before
if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repo)) throw new CommandExecutionError(...);
// after: decode + validate with decoded URI
const repo = decodeURIComponent(decodeHtmlEntities(nameMatch[1])).trim();
Defensive patterns

Strategy: try-catch

Validate before calling

const REPO_RE = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
function looksLikeRepoPath(p) { return REPO_RE.test(decodeURIComponent(String(p)).trim()); }

Type guard

function isInvalidRepoIdentity(e) { return e instanceof Error && /invalid repository identity/.test(e.message); }

Try / catch

try {
  const rows = parseTrendingHtml(html);
} catch (e) {
  if (isInvalidRepoIdentity(e)) { console.error('Scraper captured a non-repo link:', e.message); throw e; }
  throw e;
}

Prevention

When it happens

Trigger: parseTrendingHtml extracts an href from a row's h2, but after entity decoding and trimming the string fails the owner/repo pattern — for example an href to '/trending/...', '/features/...', or an oddly-encoded path captured because the h2 regex matched a broader link after markup drift.

Common situations: GitHub adds non-repo links inside the heading area (badges, org links); URL-encoded characters (e.g. %20) appearing in captured paths; markup drift causing the regex to capture the wrong href.

Related errors


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