jackwener/OpenCLI · warning · EmptyResultError

UISDC news page loaded, but no news rows with title and URL

Error message

UISDC news page loaded, but no news rows with title and URL were extracted.

What it means

After extraction, toRows filters rows to those having both a title and URL. If none survive, it throws EmptyResultError 'UISDC news page loaded, but no news rows with title and URL were extracted.' — the page loaded fine, but zero usable news items were found.

Source

Thrown at clis/uisdc/news.js:72

        throw new CommandExecutionError('UISDC news 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(
            `UISDC news 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),
            summary: normalizeText(row.summary),
            url: normalizeText(row.url),
        }))
        .filter((row) => row.title && row.url);
    if (rows.length === 0) {
        throw new EmptyResultError('uisdc news', 'UISDC news page loaded, but no news rows with title and URL were extracted.');
    }
    return rows.slice(0, limit).map((row, index) => ({ ...row, rank: index + 1 }));
}

async function loadUisdcNews(page, args) {
    const limit = normalizeLimit(args.limit);
    await page.goto(UISDC_NEWS_URL, { waitUntil: 'load', settleMs: 3000 });
    const payload = await page.evaluate(buildExtractUisdcNewsJs()).catch((error) => {
        throw new CommandExecutionError(`Failed to extract UISDC news: ${getErrorMessage(error)}`);
    });
    return toRows(payload, limit);
}

export const uisdcNewsCommand = cli({
    site: 'uisdc',
    name: 'news',
    access: 'read',
    description: '优设读报 - 最新 AI/设计行业新闻',

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the command later — the site may temporarily have no items
  2. Increase settleMs in loadUisdcNews's page.goto call to let JS-rendered content appear
  3. Check the selectors for row.title/row.url fields in buildExtractUisdcNewsJs; container may match but fields don't
  4. Confirm in a browser that the news list actually has items at UISDC_NEWS_URL

Example fix

// before
await page.goto(UISDC_NEWS_URL, { waitUntil: 'load', settleMs: 3000 });
// after
await page.goto(UISDC_NEWS_URL, { waitUntil: 'load', settleMs: 8000 });
Defensive patterns

Strategy: fallback

Validate before calling

const itemCount = await page.locator('.news-list li').count(); if (itemCount === 0) await page.waitForSelector('.news-list li', { timeout: 10000 });

Type guard

function hasUsableRows(rows) { return Array.isArray(rows) && rows.some(r => r.title && r.url); }

Try / catch

try { const rows = await loadUisdcNews(page, args); } catch (e) { if (e instanceof EmptyResultError || /no news rows/.test(e.message)) { return []; } throw e; }

Prevention

When it happens

Trigger: The extracted rows array is empty or every row lacks a non-empty title or url after normalizeText trimming (e.g. blank page, empty news list, partially rendered content).

Common situations: Site returned a valid but empty news page (holiday/maintenance); rows render via JS after the 3000ms settle window; selectors matched a container but items have different field markup so title/url come back empty.

Related errors


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