jackwener/OpenCLI · warning · EmptyResultError

aibase news

Error message

aibase news

What it means

toRows throws an EmptyResultError labeled 'aibase news' when the AIbase daily page loaded and payload.ok was true, but after normalizing and filtering, no rows had both a title and a URL. The page rendered, extraction technically succeeded, yet zero usable articles were extracted.

Source

Thrown at clis/aibase/news.js:77

    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) {
    const limit = normalizeLimit(args.limit);
    await page.goto(AIBASE_DAILY_URL, { waitUntil: 'load', settleMs: 3000 });
    const payload = await page.evaluate(buildExtractAibaseNewsJs()).catch((error) => {
        throw new CommandExecutionError(`Failed to extract AIbase daily news: ${getErrorMessage(error)}`);
    });
    return toRows(payload, limit);
}

export const aibaseNewsCommand = cli({
    site: 'aibase',
    name: 'news',
    access: 'read',
    description: 'AIbase 日报 - 每天三分钟关注AI行业趋势',

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry later — the daily page may be mid-update with placeholder content.
  2. Inspect the live page's anchors (text and href) and update the extraction script's selector/row mapping so title and url are captured.
  3. Check whether the site changed href formats (e.g. new route prefix) and adjust the script's filters.
  4. Run the whoami/login command if the variant requiring authentication shows real content while the anonymous variant shows placeholders.

Example fix

null
Defensive patterns

Strategy: fallback

Validate before calling

null

Type guard

function hasRowWithTitleAndUrl(row) {
  return !!row && typeof row.title === 'string' && row.title.trim() !== '' && typeof row.url === 'string' && row.url.trim() !== ''; 
}

Try / catch

try {
  const rows = await fetchAibaseNews();
} catch (e) {
  if (e instanceof EmptyResultError && e.operation === 'aibase news') {
    console.warn('No usable articles extracted; try again later or update extraction');
  } else throw e;
}

Prevention

When it happens

Trigger: payload.rows exists but every row lacks title or url (empty anchor text, javascript:void(0) or empty hrefs), or payload.rows is missing/not an array so the fallback [] yields length 0.

Common situations: Site renders link cards as images without text (so innerText is empty); daily edition published with placeholder links; href attributes changed to relative routes filtered out by the script; A/B variant that doesn't set the classes the row extraction expects.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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