jackwener/OpenCLI · error · CommandExecutionError
github-trending parser drift: no repository rows found
Error message
github-trending parser drift: no repository rows found
What it means
parseTrendingHtml found zero `<article class="Box-row">` blocks in the fetched GitHub Trending HTML. If the page does not explicitly say there are no trending repositories, the library assumes the page layout changed and throws this CommandExecutionError rather than silently returning an empty list — this is a scraper-integrity safeguard against parser drift.
Source
Thrown at clis/github-trending/repos.js:57
if (count == null) {
throw new CommandExecutionError(`github-trending parser drift: missing ${field} for ${repo}`);
}
return count;
}
function hasExplicitEmptyTrending(html) {
return /don.t have any trending repositories/i.test(stripTags(html))
|| /no trending repositories/i.test(stripTags(html));
}
function parseTrendingHtml(html, limit) {
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()
: '';View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the command — transient bot-challenges and deploys often resolve on retry
- Check what the URL returns in a browser/curl to confirm whether real HTML comes back
- Upgrade the CLI package to get updated parser selectors
- Verify the language slug is a valid GitHub language (invalid paths may render unexpected pages)
Defensive patterns
Strategy: fallback
Validate before calling
null
Type guard
function isParserDrift(e) { return e instanceof Error && /parser drift/.test(e.message); } Try / catch
try {
const rows = parseTrendingHtml(html);
} catch (e) {
if (/no repository rows found/.test(e.message)) { alertMaintainer(e); return []; }
throw e;
} Prevention
- Confirm the fetched HTML is the real trending page (not a bot-challenge) before parsing
- Retry transient failures before treating them as parser drift
- Keep selectors updated with new releases of the CLI
When it happens
Trigger: Fetching /trending (or a language-filtered trending path) returns HTML with no Box-row article elements and no 'don't have any trending repositories' message — e.g. a login wall, bot-challenge page, empty/error page, or a GitHub markup change.
Common situations: GitHub A/B-testing a redesigned trending page; response being an interstitial (rate-limit, sign-in, or CAPTCHA page); language path with genuinely no trending repos rendered differently than the empty-state text the parser checks; CDN/error page returned instead of real HTML.
Related errors
- github-trending parser drift: missing ${field} for ${repo}
- github-trending parser drift: missing repository link
- github-trending parser drift: invalid repository identity "$
- autohome brand catalog returned an unexpected HTML shape; ex
- No koubei data found — the series id may be wrong, or Autoho
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/7bb81d1ac9e9ddb9.
Report an issue: GitHub.