jackwener/OpenCLI · error · CommandExecutionError

${actionLabel} failed: ${result?.error || 'invalid browser r

Error message

${actionLabel} failed: ${result?.error || 'invalid browser response'}

What it means

readHupuNextData waits up to ~5s for the page's `__NEXT_DATA__` script tag (optionally matching an expected tid) and parses it. If page.evaluate returns a falsy/non-object value, or `{ok:false, error}` (timeout, tid mismatch, or JSON.parse failure inside the browser), the helper throws CommandExecutionError with the browser-reported error, or the fallback 'invalid browser response' when result itself is unusable. It means Hupu's Next.js page data never became available or was not parseable.

Source

Thrown at clis/hupu/utils.js:97

        };
      }

      try {
        const text = document.getElementById('__NEXT_DATA__')?.textContent || '';
        return {
          ok: true,
          data: JSON.parse(text)
        };
      } catch (error) {
        return {
          ok: false,
          error: error instanceof Error ? error.message : String(error)
        };
      }
    })()
  `);
    if (!result || typeof result !== 'object' || !result.ok) {
        throw new CommandExecutionError(`${actionLabel} failed: ${result?.error || 'invalid browser response'}`);
    }
    return result.data;
}
export async function readHupuSearchData(page, url, actionLabel) {
    await page.goto(url);
    const result = await page.evaluate(`
    (async () => {
      const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
      const waitFor = async (predicate, timeoutMs = 5000) => {
        const start = Date.now();
        while (Date.now() - start < timeoutMs) {
          if (predicate()) return true;
          await wait(100);
        }
        return false;
      };

      const extractFromScript = () => {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the inner message (tid mismatch includes expected/actual tid and href) to see whether it was a timeout, tid mismatch, or missing data.
  2. Verify the tid/URL is a valid, existing thread and that the page loads in a normal browser.
  3. Increase options.timeoutMs if the network is slow; re-run the command.
  4. Log in to Hupu (or refresh cookies) if the site is serving an anti-bot or login page instead of thread data.
  5. If __NEXT_DATA__ is gone entirely, the site changed rendering — the CLI needs a parser update.

Example fix

// before
const data = await readHupuNextData(page, url, 'Read thread', { expectedTid: tid });
// after — give slow pages more time and validate tid first
if (!/^\d{9}$/.test(String(tid))) throw new Error(`invalid tid: ${tid}`);
const data = await readHupuNextData(page, url, 'Read thread', { expectedTid: String(tid), timeoutMs: 15000 });
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check the target thread before extraction
const res = await page.goto(threadUrl);
if (!res || !res.ok()) throw new Error(`thread page unreachable: ${threadUrl}`);
const hasNextData = await page.evaluate(() => Boolean(document.getElementById('__NEXT_DATA__')));
if (!hasNextData) console.warn('__NEXT_DATA__ not yet present; may need login or longer wait');

Type guard

function isNextDataResult(r) {
  return typeof r === 'object' && r !== null && 'ok' in r && (r.ok !== true || 'data' in r);
}

Try / catch

try {
  const data = await readHupuNextData(page, url, 'Read thread', { expectedTid, timeoutMs: 15000 });
} catch (err) {
  if (/tid不匹配/.test(err.message)) {
    const m = err.message.match(/expected=([^,]+), actual=([^,]+)/);
    console.error(`Redirected thread: wanted ${m?.[1]}, got ${m?.[2]}`);
  } else if (/无法找到帖子数据/.test(err.message)) {
    await refreshSession(); // likely a login/anti-bot wall
  }
  throw err;
}

Prevention

When it happens

Trigger: Any hupu read command backed by readHupuNextData when: the thread page never renders __NEXT_DATA__ within timeoutMs (default 5000), the rendered thread's tid differs from options.expectedTid (redirect/wrong tid), __NEXT_DATA__ is malformed JSON, or page.evaluate returns undefined/null so result?.error is undefined.

Common situations: Deleted or wrong thread tid causing a redirect to a different thread, Hupu serving a login/verification wall instead of the data page, slow network exceeding the 5s timeout, or Hupu changing its page framework so __NEXT_DATA__ no longer exists.

Related errors


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