jackwener/OpenCLI · error · CommandExecutionError
Zhihu ${label} returned malformed paging state
Error message
Zhihu ${label} returned malformed paging state What it means
CommandExecutionError thrown when payload.paging exists but paging.is_end is not a boolean. The pagination loop relies on is_end to know when to stop fetching pages; without a definitive boolean it cannot terminate safely, so the library refuses to continue.
Source
Thrown at clis/zhihu/answer-comments-helpers.js:85
if (status >= 400 || code || payload.__errorMessage || payload.__needLogin) {
if (code === '40362') {
throw new CommandExecutionError(
`Zhihu risk control blocked ${label} (40362): ${payload.__errorMessage || 'abnormal request'}`,
'Open the answer in the connected Chrome profile and retry later.',
);
}
if (status === 401 || status === 403 || code === '40353' || payload.__needLogin) {
throw new AuthRequiredError('www.zhihu.com', `Failed to fetch Zhihu ${label}`);
}
if (status === 404 && notFoundDetail) throw new EmptyResultError('zhihu answer-comments', notFoundDetail);
if (status >= 400) throw new CommandExecutionError(`Zhihu ${label} request failed (HTTP ${status})`);
throw new CommandExecutionError(`Zhihu ${label} returned an error payload: ${payload.__errorMessage || code}`);
}
if (!Array.isArray(payload.data) || !payload.paging || typeof payload.paging !== 'object') {
throw new CommandExecutionError(`Zhihu ${label} returned a malformed payload`);
}
if (typeof payload.paging.is_end !== 'boolean') {
throw new CommandExecutionError(`Zhihu ${label} returned malformed paging state`);
}
return payload;
}
function describeComment(comment, role, expectedRootId = '') {
if (!comment || typeof comment !== 'object' || Array.isArray(comment)) {
throw new CommandExecutionError(`Zhihu answer comments contained a malformed ${role} row`);
}
const id = commentId(comment.id);
if (!id) throw new CommandExecutionError(`Zhihu answer comments contained a ${role} row without a stable id`);
const rootId = role === 'root' ? id : commentId(comment.reply_root_comment_id);
const parentId = role === 'root' ? '' : commentId(comment.reply_comment_id);
if (role === 'child' && rootId !== expectedRootId) {
throw new CommandExecutionError(`Zhihu answer comment ${id} had conflicting root provenance`);
}
if (role === 'child' && !parentId) {
throw new CommandExecutionError(`Zhihu answer comment ${id} did not identify its immediate parent`);
}
const signature = JSON.stringify({View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect paging with -v to see what fields Zhihu now returns
- Coerce defensively: treat missing is_end as false only when next link is absent, otherwise stop after N pages as a safeguard
- Update the parser if Zhihu renamed/moved the field (e.g. paging.is_end -> another key)
- Add a max-page cap in your loop so any pagination anomaly terminates the fetch
Example fix
// before
while (!done) { const p = await fetchCommentPage(url); done = p.paging.is_end; } // throws on non-boolean
// after
let pages = 0;
while (!done && pages++ < 50) { const p = await fetchCommentPage(url); done = p.paging?.is_end === true || !p.paging?.next; } Defensive patterns
Strategy: validation
Validate before calling
const body = await res.json(); if (typeof body?.paging?.is_end !== 'boolean') throw new Error('paging.is_end missing/non-boolean: ' + JSON.stringify(body?.paging)); Type guard
function hasValidPaging(p){ return typeof p?.paging?.is_end === 'boolean'; } Try / catch
try { await fetchCommentPage(url); } catch (e) { if (/malformed paging/.test(e.message)) { /* stop paginating with a safe default or inspect paging keys */ } throw e; } Prevention
- Always cap pagination loops with a max-page limit
- Treat missing is_end as end-of-pages when no next link exists
- Log the paging object when pagination behavior changes
- Add an assertion test on paging metadata shape
When it happens
Trigger: The Zhihu comment response's paging object omitted is_end or typed it as something else (string 'true', number, undefined) — a schema deviation on the pagination metadata.
Common situations: Zhihu changing pagination metadata format; last-page responses omitting is_end; paginated endpoints for new content types behaving differently.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Jike notifications API returned a malformed pagination curso
- Midjourney history endpoint returned a malformed payload
- Zhihu ${label} returned a malformed payload
- Zhihu answer comments contained a malformed ${role} row
- Zhihu answer comments returned conflicting data for comment
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/533548625ca55f87.
Report an issue: GitHub.