jackwener/OpenCLI · error · EmptyResultError

Tieba did not land on the requested thread page

Error message

Tieba did not land on the requested thread page

What it means

`tieba read` navigates to a thread page (`/p/<id>`) and then asserts, inside `assertTiebaReadTargetPage`, that the browser actually landed on the thread matching `kwargs.id`. This EmptyResultError is thrown when the final URL's pathname does not contain the expected thread id (or the pathname is not a thread page at all). The library treats a wrong-destination navigation as an empty result rather than returning data from the wrong thread, which would silently produce incorrect content.

Source

Thrown at clis/tieba/read.js:19

import { EmptyResultError } from '@jackwener/opencli/errors';
import { cli, Strategy } from '@jackwener/opencli/registry';
import { buildTiebaReadItems } from './utils.js';
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();

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the thread id passed via --id (or kwargs.id) is a valid numeric Tieba thread id and still exists (open https://tieba.baidu.com/p/<id> manually).
  2. Re-run the command; transient anti-bot/captcha redirects usually clear on retry, ideally with a persisted logged-in browser profile.
  3. Check whether the page redirected (log raw.pageMeta.pathname) to identify a captcha/login wall, and complete login/verification in the browser session first.
  4. If pageMeta is consistently empty, update the library — Tieba likely changed its page structure.

Example fix

// before
await cli.read({ id: '12345', page: 2 }); // thread deleted -> redirected -> EmptyResultError
// after
// verify the thread exists first, or handle the redirect
curl -sI https://tieba.baidu.com/p/12345 | head -n1 // confirm 200 before calling
Defensive patterns

Strategy: validation

Validate before calling

// pre-validate before calling tieba read
if (!/^\d+$/.test(String(threadId))) {
  throw new Error('tieba thread id must be numeric');
}

Type guard

function isValidTiebaThreadId(id) {
  return typeof id === 'string' && /^\d+$/.test(id);
}

Try / catch

import { EmptyResultError } from '@jackwener/opencli/errors';
try {
  return await cli.read({ id: threadId, page });
} catch (e) {
  if (e instanceof EmptyResultError) {
    // wrong-destination navigation: check redirect/captcha, retry once
    return retryWithBackoff(() => cli.read({ id: threadId, page }), 1);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `tieba read --id <threadId>` when the browser is redirected to a different URL: the thread id in the URL does not match `--id`, the pathname is not `/p/<digits>` (e.g. redirected to a login/verify/captcha page or the tieba home), or `raw.pageMeta.pathname` is empty because page metadata extraction failed.

Common situations: Baidu Tieba redirects deleted, private, or banned threads to an interstitial or the forum list; anti-bot verification pages replace the thread URL; passing a wrong/typo'd thread id; the page loaded inside an iframe or SPA state where pageMeta was not captured.

Related errors


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