jackwener/OpenCLI · error · CommandExecutionError

AIbase daily selector drift

Error message

AIbase daily selector drift: ${reason}

What it means

toRows throws this CommandExecutionError when the extraction script reports payload.ok === false, meaning the page loaded but the expected DOM selectors matched nothing. The reason comes from the script ('selector-missing') or defaults to 'selector-drift', and the error detail may include the page title to help diagnose what actually rendered.

Solutions

  1. Check the Page title detail in the error to identify what page actually rendered (captcha, consent wall, redesign).
  2. Retry later — if it's a temporary interstitial or empty daily edition it may resolve.
  3. Update the CSS selectors in buildExtractAibaseNewsJs to match the site's current DOM (inspect the live page).
  4. Clear/refresh the browser session (opencli aibase login) if a stale session or cookie wall is causing the alternate page.

Example fix

// before
const anchors = Array.from(document.querySelectorAll('.bg-white .grid a[href], a[href*="/zh/daily/"]'))
// after (selectors updated to the site's new markup)
const anchors = Array.from(document.querySelectorAll('.daily-list a.article-link, a[href*="/zh/daily/"]'))
Defensive patterns

Strategy: fallback

Validate before calling

null

Type guard

function hasExpectedRows(payload) {
  return !!payload && typeof payload === 'object' && payload.ok === true && Array.isArray(payload.rows) && payload.rows.length > 0;
}

Try / catch

try {
  await runCommand(['aibase', 'news']);
} catch (e) {
  if (e instanceof CommandExecutionError && e.message.includes('selector drift')) {
    console.error('Site markup changed; check Page title detail and update selectors');
  } else throw e;
}

Prevention

When it happens

Trigger: The injected script finds zero anchors matching '.bg-white .grid a[href]' or 'a[href*="/zh/daily/"]' and returns {ok:false, reason:'selector-missing', ...}; or returns ok:false with any other reason.

Common situations: AIbase redesigned its daily page (class names/structure changed); an anti-bot or consent interstitial replaced the article grid; the page served a regional variant or an empty daily edition with no articles; A/B tests altering markup.

Related errors


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

Appendix: source

Thrown at clis/aibase/news.js:64

          seen.add(url);
          rows.push({
            rank: rows.length + 1,
            title: anchor.innerText || anchor.textContent || '',
            url,
          });
        }
        return { ok: true, rows };
      })()
    `;
}

function toRows(payload, limit) {
    if (!payload || typeof payload !== 'object') {
        throw new CommandExecutionError('AIbase daily page returned an unreadable payload');
    }
    if (!payload.ok) {
        const reason = typeof payload.reason === 'string' && payload.reason.trim() ? payload.reason.trim() : 'selector-drift';
        throw new CommandExecutionError(
            `AIbase daily selector drift: ${reason}`,
            payload.title ? `Page title: ${payload.title}` : undefined,
        );
    }
    const rows = (Array.isArray(payload.rows) ? payload.rows : [])
        .map((row, index) => ({
            rank: index + 1,
            title: normalizeText(row.title),
            url: normalizeText(row.url),
        }))
        .filter((row) => row.title && row.url);
    if (rows.length === 0) {
        throw new EmptyResultError('aibase news', 'AIbase daily page loaded, but no article rows with title and URL were extracted.');
    }
    return rows.slice(0, limit).map((row, index) => ({ ...row, rank: index + 1 }));
}

async function loadAibaseNews(page, args) {

View on GitHub (pinned to 49907e53dc)