jackwener/OpenCLI · error · EmptyResultError

Tieba did not land on the requested page

Error message

Tieba did not land on the requested page

What it means

When `tieba read` is asked for a page beyond the first (`kwargs.page > 1`), `assertTiebaReadTargetPage` compares the actual `pn` query parameter captured in `raw.pageMeta.pn` with the requested page number and throws this EmptyResultError on mismatch. This guards against returning page-1 content when the caller asked for a later page — a common failure because Tieba pagination via URL often snaps back to page 1. The library refuses to return mis-paginated data.

Source

Thrown at clis/tieba/read.js:22

function getThreadUrl(kwargs) {
    const threadId = String(kwargs.id || '');
    const pageNumber = Math.max(1, Number(kwargs.page || 1));
    return `https://tieba.baidu.com/p/${encodeURIComponent(threadId)}?pn=${pageNumber}`;
}
/**
 * Ensure the browser actually landed on the requested thread page before we trust the DOM.
 */
function assertTiebaReadTargetPage(raw, kwargs) {
    const expectedThreadId = String(kwargs.id || '').trim();
    const expectedPageNumber = Math.max(1, Number(kwargs.page || 1));
    const pathname = String(raw.pageMeta?.pathname || '').trim();
    const actualThreadId = pathname.match(/^\/p\/(\d+)/)?.[1] || '';
    const actualPn = String(raw.pageMeta?.pn || '').trim();
    if (!actualThreadId || actualThreadId !== expectedThreadId) {
        throw new EmptyResultError('tieba read', 'Tieba did not land on the requested thread page');
    }
    if (expectedPageNumber > 1 && actualPn !== String(expectedPageNumber)) {
        throw new EmptyResultError('tieba read', 'Tieba did not land on the requested page');
    }
}
function buildExtractReadEvaluate() {
    return `
    (async () => {
      const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
      const waitFor = async (predicate, timeoutMs = 4000) => {
        const start = Date.now();
        while (Date.now() - start < timeoutMs) {
          if (predicate()) return true;
          await wait(100);
        }
        return false;
      };
      const normalizeText = (value) => (value || '').replace(/\\s+/g, ' ').trim();
      const getVueProps = (element) => {
        const vue = element && element.__vue__ ? element.__vue__ : null;
        return vue ? (vue._props || vue.$props || {}) : {};

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check the thread actually has the requested page count; reduce --page if the thread is shorter (Tieba silently falls back to an earlier page).
  2. Re-run — a transient navigation race may land on the wrong page; add a small delay or retry.
  3. Fetch page 1 first and inspect its total-page metadata to determine a valid max page before requesting higher pages.
  4. If it persists on valid pages, the pageMeta extraction (raw.pageMeta.pn) is likely broken by a Tieba DOM/URL change — update the library.

Example fix

// before
await cli.read({ id: '12345', page: 99 }); // thread only has 3 pages -> clamped -> EmptyResultError
// after
const first = await cli.read({ id: '12345', page: 1 });
const lastPage = first.pageMeta?.totalPage ?? 1;
await cli.read({ id: '12345', page: Math.min(3, lastPage) });
Defensive patterns

Strategy: validation

Validate before calling

// confirm requested page is plausible before calling
if (!Number.isInteger(page) || page < 1) {
  throw new Error('page must be a positive integer');
}

Type guard

function isValidTiebaPage(page) {
  return Number.isInteger(page) && page >= 1;
}

Try / catch

try {
  return await cli.read({ id: threadId, page });
} catch (e) {
  if (e instanceof EmptyResultError && page > 1) {
    // thread may be shorter than requested: fall back to page 1
    return cli.read({ id: threadId, page: 1 });
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `tieba read --id <threadId> --page N` (N>1) when the landed page's `pn` query param is not N: the thread has fewer pages than requested (Tieba clamps/redirects to last or first page), the pagination click/goto did not take effect, or pageMeta.pn was not extracted.

Common situations: Requesting a page number beyond the thread's total page count; deleted/filtered posts shrinking the page count between runs; SPA pagination that doesn't update the URL; scraping automation racing ahead of navigation completion.

Related errors


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