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
- Upgrade the scraper package for updated regexes matching current markup
- Check the captured value in the message to see what the regex matched and adjust the pattern
- 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
- URI-decode captured paths before validating in local patches
- Keep the owner/repo validation regex in sync with GitHub URL conventions
- Report recurring captures of non-repo links upstream with sample HTML
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
- github-trending parser drift: missing ${field} for ${repo}
- github-trending parser drift: no repository rows found
- github-trending parser drift: missing repository link
- ${label} did not include a stable numeric id.
- ${label} did not include a stable text value.
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a735eb7339fd5272.
Report an issue: GitHub.