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
- Check the thread actually has the requested page count; reduce --page if the thread is shorter (Tieba silently falls back to an earlier page).
- Re-run — a transient navigation race may land on the wrong page; add a small delay or retry.
- Fetch page 1 first and inspect its total-page metadata to determine a valid max page before requesting higher pages.
- 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
- Discover total page count from page-1 metadata before requesting higher pages.
- Clamp requested page to the thread's actual last page.
- Treat page-1 fallback as the standard recovery for out-of-range pages.
- Cache thread page counts to avoid repeated out-of-range requests.
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
- Sales Navigator messaging threads API returned the same curs
- rednote/user
- Tieba may have blocked the hot page, or the DOM structure ma
- Tieba may have blocked the forum page, or the DOM structure
- Tieba did not land on the requested thread page
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/9424dcd59a9a31b3.
Report an issue: GitHub.