{"record":{"id":"dab3e2a802739edc","repo":"jackwener/OpenCLI","slug":"zhihu-label-returned-a-malformed-payload","errorCode":null,"errorMessage":"Zhihu ${label} returned a malformed payload","messagePattern":"Zhihu (.+?) returned a malformed payload","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/zhihu/answer-comments-helpers.js","lineNumber":63,"sourceCode":"        const result = {\n            __httpStatus: response.status,\n            __errorCode: error?.code ?? body?.error_code ?? '',\n            __errorMessage: error?.message || body?.error_msg || '',\n            __needLogin: error?.need_login === true || body?.need_login === true,\n        };\n        return !response.ok || result.__errorCode || result.__errorMessage || result.__needLogin ? result : body;\n    }, url).catch((error) => {\n        throw new CommandExecutionError(\n            `Zhihu ${label} request failed: ${error instanceof Error ? error.message : String(error)}`,\n            'Try again later or rerun with -v for more detail.',\n        );\n    });\n    const payload = unwrapEvaluateResult(evaluated);\n    if (payload?.__malformedJson) {\n        throw new CommandExecutionError(`Zhihu ${label} returned malformed JSON: ${payload.__malformedJson}`);\n    }\n    if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {\n        throw new CommandExecutionError(`Zhihu ${label} returned a malformed payload`);\n    }\n    const status = payload.__httpStatus;\n    const code = String(payload.__errorCode || '');\n    if (status >= 400 || code || payload.__errorMessage || payload.__needLogin) {\n        if (code === '40362') {\n            throw new CommandExecutionError(\n                `Zhihu risk control blocked ${label} (40362): ${payload.__errorMessage || 'abnormal request'}`,\n                'Open the answer in the connected Chrome profile and retry later.',\n            );\n        }\n        if (status === 401 || status === 403 || code === '40353' || payload.__needLogin) {\n            throw new AuthRequiredError('www.zhihu.com', `Failed to fetch Zhihu ${label}`);\n        }\n        if (status === 404 && notFoundDetail) throw new EmptyResultError('zhihu answer-comments', notFoundDetail);\n        if (status >= 400) throw new CommandExecutionError(`Zhihu ${label} request failed (HTTP ${status})`);\n        throw new CommandExecutionError(`Zhihu ${label} returned an error payload: ${payload.__errorMessage || code}`);\n    }\n    if (!Array.isArray(payload.data) || !payload.paging || typeof payload.paging !== 'object') {","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/zhihu/answer-comments-helpers.js#L45-L81","documentation":"Thrown when the evaluated result is not a usable object: either null/undefined, a non-object, or an Array. fetchCommentPage expects Zhihu's comment API shape ({data, paging, ...}), so anything else is rejected as a malformed payload. This catches cases where the in-page fetch succeeded but the unwrapped result lost its structure.","triggerScenarios":"unwrapEvaluateResult returned null/undefined, a primitive, or an array — e.g. the evaluate returned nothing, serialization dropped the value, or the endpoint returned a JSON array / bare string rather than an object.","commonSituations":"Older Zhihu API versions returning a JSON array at the top level; evaluate serialization failures in the Chrome bridge; endpoints that redirect to non-API content.","solutions":["Log the raw evaluated value with -v to see what shape came back","If the API changed shape (top-level array), update the parsing code to normalize it before this check","Reconnect/refresh the Chrome profile so evaluate returns values correctly","Retry — a transient empty response can pass on a second attempt"],"exampleFix":"// before\n// fetchCommentPage rejects arrays outright\nif (!payload || typeof payload !== 'object' || Array.isArray(payload)) throw ...\n// after\n// normalize a top-level array into the expected shape before validation\nlet payload = unwrapEvaluateResult(evaluated);\nif (Array.isArray(payload)) payload = { data: payload, paging: {} };","handlingStrategy":"type-guard","validationCode":"if (evaluated == null || typeof evaluated !== 'object') { /* abort before validation */ }","typeGuard":"function isPayloadObject(p){ return p !== null && typeof p === 'object' && !Array.isArray(p); }","tryCatchPattern":"try { await fetchCommentPage(url); } catch (e) { if (String(e.message).includes('malformed payload')) { /* re-evaluate with verbose logging or normalize input */ } else throw e; }","preventionTips":["Ensure the evaluate bridge returns structured-cloneable objects","Normalize known top-level arrays to {data: arr, paging:{}} upstream","Log raw evaluate results when debugging","Pin/monitor Zhihu API versions used by the fetch helper"],"tags":["zhihu","schema-validation","serialization"],"backgroundTag":"unexpected-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}