jackwener/OpenCLI · error · CommandExecutionError
toutiao articles render failed: ${error?.message || error}
Error message
toutiao articles render failed: ${error?.message || error} What it means
The toutiao articles command renders the creator-backend page in a browser and extracts body text via an injected async IIFE; any failure inside that evaluation is re-thrown as a CommandExecutionError 'toutiao articles render failed: <msg>'. It wraps navigation timeouts, script errors, or page crashes from the render step.
Source
Thrown at clis/toutiao/articles.js:35
args: [
{ name: 'page', type: 'int', default: 1, help: '页码 (1-4)' },
],
columns: ['title', 'date', 'status', '展现', '阅读', '点赞', '评论'],
func: async (page, kwargs) => {
const articlePage = parseArticlesPage(kwargs.page, 1);
let text;
try {
await page.goto(`https://mp.toutiao.com/profile_v4/manage/content/all?page=${articlePage}`);
await page.wait('networkidle');
await page.wait(3);
text = await page.evaluate(`
(async () => {
await new Promise(r => setTimeout(r, 2000));
return document.body.innerText || '';
})()
`);
} catch (error) {
throw new CommandExecutionError(`toutiao articles render failed: ${error?.message || error}`);
}
if (looksToutiaoAuthWallText(text)) {
throw new AuthRequiredError('mp.toutiao.com', 'Toutiao creator articles require a logged-in mp.toutiao.com browser session');
}
const rows = parseToutiaoArticlesText(text);
if (rows.length === 0) {
throw new EmptyResultError(
'toutiao articles',
`未抓取到创作者后台文章 (page=${articlePage})。可能页面尚未完成渲染或无文章。`,
);
}
return rows;
},
});
export { parseToutiaoArticlesText };
export const __test__ = {
parseToutiaoArticlesText,View on GitHub (pinned to 49907e53dc)
Solutions
- Read the embedded message for the root cause (timeout vs crash vs script error)
- Increase the render/navigation timeout and the 2000ms settle delay
- Retry the command once — transient load issues often resolve
- Verify the headless browser can load mp.toutiao.com at all (test manually / non-headless)
Example fix
// before
await new Promise(r => setTimeout(r, 2000));
return document.body.innerText || '';
// after
await page.waitForSelector('.article-list, body', { timeout: 15000 });
await new Promise(r => setTimeout(r, 3000));
return document.body.innerText || ''; Defensive patterns
Strategy: try-catch
Validate before calling
await page.goto('https://mp.toutiao.com', { waitUntil: 'domcontentloaded', timeout: 30000 });
if (!document_title_ok) await page.waitForSelector('body', { timeout: 15000 }); Type guard
function isRenderFailure(e) { return /toutiao articles render failed/i.test(e?.message || ''); } Try / catch
try { await fetchToutiaoArticles(); } catch (e) {
if (isRenderFailure(e)) {
await sleep(5000); return fetchToutiaoArticles(); // bounded retry
}
throw e;
} Prevention
- Raise navigation and settle timeouts for slow loads
- Wait for a real content selector instead of fixed 2s
- Keep the browser alive and healthy (avoid closing pages mid-render)
- Test headless vs headless=false if the page misbehaves
When it happens
Trigger: The page.evaluate-style call running the IIFE (2s wait then document.body.innerText) threw — navigation timeout, page closed/crashed, or the evaluation itself errored.
Common situations: Slow network so mp.toutiao.com didn't load within the timeout; browser crashed or was closed mid-render; Toutiao serving a challenge that breaks script execution; headless incompatibility with the page.
Related errors
- Failed to upload file to ChatGPT project knowledge
- Failed to send message to ChatGPT
- Failed to read GeoGebra object property: ${err?.message || e
- Manus whoami failed: ${probe.detail}
- ${probe.detail}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0e5ebf3866973294.
Report an issue: GitHub.