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
- Read the inner message (tid mismatch includes expected/actual tid and href) to see whether it was a timeout, tid mismatch, or missing data.
- Verify the tid/URL is a valid, existing thread and that the page loads in a normal browser.
- Increase options.timeoutMs if the network is slow; re-run the command.
- Log in to Hupu (or refresh cookies) if the site is serving an anti-bot or login page instead of thread data.
- 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
- Pass a higher timeoutMs on slow networks instead of the 5s default.
- Always pass expectedTid so redirects/mismatches are detected with a clear message.
- Verify the thread exists in a normal browser before assuming a CLI bug.
- Keep the session logged in — data pages behind login walls lack __NEXT_DATA__.
- Watch for Hupu frontend changes: if __NEXT_DATA__ disappears site-wide, extraction logic needs updating.
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
- Not a git repository
- Working tree not clean: ${status}
- Ctrip place page did not render attraction links for city id
- Ctrip attraction DOM extraction returned malformed rows
- Ctrip attraction links rendered but parser did not find requ
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/765f01355c1e740d.
Report an issue: GitHub.