{"record":{"id":"e5246c71799f3b5b","repo":"jackwener/OpenCLI","slug":"zhihu-user-articles-returned-malformed-row-identit","errorCode":null,"errorMessage":"Zhihu user articles returned malformed row identity","messagePattern":"Zhihu user articles returned malformed row identity","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/zhihu/user-articles.js","lineNumber":28,"sourceCode":"    name: 'user-articles',\n    access: 'read',\n    description: '知乎某用户的文章/专栏列表',\n    domain: 'www.zhihu.com',\n    strategy: Strategy.COOKIE,\n    args: [\n        { name: 'user', type: 'string', required: true, positional: true, help: 'User url_token or people URL' },\n        { name: 'limit', type: 'int', default: 20, help: 'Number of articles to return (max 1000)' },\n    ],\n    columns: ['rank', 'title', 'votes', 'comments', 'created', 'url'],\n    func: async (page, kwargs) => {\n        const slug = parseZhihuUser(kwargs.user);\n        const limit = validateLimit(kwargs.limit);\n        await page.goto('https://www.zhihu.com');\n        const first = `https://www.zhihu.com/api/v4/members/${encodeURIComponent(slug)}/articles?limit=20&offset=0&include=${encodeURIComponent(INCLUDE)}`;\n        const items = await fetchZhihuList(page, first, limit, 'user articles');\n        return items.map((a, i) => {\n            if (!a.id || !a.title) {\n                throw new CommandExecutionError('Zhihu user articles returned malformed row identity');\n            }\n            return {\n                rank: i + 1,\n                title: String(a.title || ''),\n                votes: a.voteup_count ?? 0,\n                comments: a.comment_count ?? 0,\n                created: a.created ?? a.updated ?? 0,\n                url: `https://zhuanlan.zhihu.com/p/${a.id}`,\n            };\n        });\n    },\n});\n","sourceCodeStart":10,"sourceCodeEnd":41,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/zhihu/user-articles.js#L10-L41","documentation":"After fetching a Zhihu user's article list from the members/<slug>/articles API, each row is validated: an item without both id and title indicates the API returned rows this CLI cannot identify, so it throws CommandExecutionError('Zhihu user articles returned malformed row identity') rather than emitting a garbage row.","triggerScenarios":"Running the user-articles command when Zhihu's v4 articles API returns items lacking id or title — e.g. an API shape change, protected/deleted articles rendered as stubs, anti-scraping interstitials, or partial/limit-offset responses returning placeholder objects.","commonSituations":"Zhihu deploying a new API response shape; anonymous scraping sessions getting degraded data; include= projection returning fewer fields than expected; pagination windows hitting hidden articles.","solutions":["Rerun the command; transient/anti-bot responses often resolve on retry","Lower --limit so fewer rows are fetched per page","Verify the user slug is correct (a wrong slug can return odd payloads)","Update the CLI/library to a version matching the current Zhihu API shape"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function looksLikeArticleRow(a) { return a && typeof a === 'object' && (a.id !== undefined && a.id !== null) && (typeof a.title === 'string' && a.title.length > 0); }\n// precheck after fetch, before mapping\nif (Array.isArray(items) && items.length && !items.every(looksLikeArticleRow)) { /* retry or bail */ }","typeGuard":"const hasRowIdentity = (a) => typeof a === 'object' && a !== null && 'id' in a && typeof a.title === 'string' && a.title.length > 0;","tryCatchPattern":"try {\n  const articles = await getUserArticles(slug, limit);\n} catch (e) {\n  if (e.message.includes('malformed row identity')) {\n    await sleep(2000); // backoff and retry once; else surface API-shape issue\n  } else throw e;\n}","preventionTips":["Pin and regularly update the library so API-shape changes are patched","Filter obviously stub/hidden rows before mapping instead of failing the whole batch","Log the raw API response on failure for debugging","Reduce page size (limit) to lower the chance of degraded responses"],"tags":["api","zhihu","response-shape"],"backgroundTag":"malformed-api-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}