{"record":{"id":"047c18a98a5a8346","repo":"jackwener/OpenCLI","slug":"zhihu-search-returned-malformed-result-row-identit","errorCode":null,"errorMessage":"Zhihu search returned malformed result row identity","messagePattern":"Zhihu search returned malformed result row identity","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/zhihu/search.js","lineNumber":110,"sourceCode":"    }\n    if (!payload.paging || typeof payload.paging !== 'object') {\n        throw new CommandExecutionError('Zhihu search returned malformed paging data', `URL: ${url}`);\n    }\n    return payload;\n}\n\nfunction normalizeResultItem(item) {\n    if (!item || typeof item !== 'object' || item.type !== 'search_result' || !item.object || typeof item.object !== 'object') {\n        return null;\n    }\n    const obj = item.object;\n    if (obj.type !== 'answer' && obj.type !== 'article' && obj.type !== 'question') return null;\n    const key = itemKey(item);\n    const url = itemUrl(obj);\n    const question = obj.question || {};\n    const title = stripHtml(obj.title || question.name || question.title || '');\n    if (!key || !url || !title) {\n        throw new CommandExecutionError('Zhihu search returned malformed result row identity');\n    }\n    return {\n        item,\n        key,\n        row: {\n            title,\n            type: obj.type,\n            author: obj.author?.name || '',\n            votes: obj.voteup_count || 0,\n            url,\n        },\n    };\n}\n\ncli({\n    site: 'zhihu',\n    name: 'search',\n    access: 'read',","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/zhihu/search.js#L92-L128","documentation":"normalizeResultItem validates that each search result row has an identity triple: a recognized type (answer/article/question), a non-empty key, URL, and title. If any of these is missing after normalization (itemKey/itemUrl return empty or title strips to empty), the CLI throws this CommandExecutionError because a row without identity cannot be displayed or linked reliably. It is a defensive guard against Zhihu's search API returning incomplete or unexpected objects.","triggerScenarios":"A search result object from Zhihu's API has type answer/article/question but itemKey(item) returns empty, itemUrl(obj) yields no URL, or stripHtml of obj.title/question.name/question.title produces an empty string.","commonSituations":"Zhihu changes its search API shape (renamed fields), soft-deleted or moderated items appear with empty titles, or scraping/HTML-stripping removes all content from a title, or a new result type passes the type check but lacks the key the itemKey function expects.","solutions":["Update/re-run the search; malformed rows are often transient upstream data issues","Check the raw API response (log data.data items) to see which field is missing","Update the itemKey/itemUrl/stripHtml helpers to match the current Zhihu API field names","Skip malformed rows (return null) instead of throwing if you control the fork"],"exampleFix":"// before\nif (!key || !url || !title) {\n    throw new CommandExecutionError('Zhihu search returned malformed result row identity');\n}\n// after\nif (!key || !url || !title) {\n    console.warn('skipping malformed row', item);\n    return null;\n}","handlingStrategy":"validation","validationCode":"function isUsableRow(item) {\n  const t = item?.target;\n  return t && ['answer','article','question'].includes(t.type) &&\n    !!t.id && !!(t.title || t.question?.title || t.question?.name);\n}\nconst usable = (data.data || []).filter(isUsableRow);","typeGuard":"function hasRowIdentity(obj) {\n  return typeof obj === 'object' && obj !== null &&\n    typeof obj.type === 'string' &&\n    ['answer','article','question'].includes(obj.type) &&\n    typeof obj.title === 'string' && obj.title.trim() !== '' &&\n    typeof obj.url === 'string' && obj.url !== '';\n}","tryCatchPattern":"try {\n  const results = await zhihuSearch(query, opts);\n} catch (err) {\n  if (err.message.includes('malformed result row identity')) {\n    console.error('Zhihu API returned an unidentifiable row; retry or inspect raw payload', err);\n  } else throw err;\n}","preventionTips":["Pre-filter API items for id/title/url presence before passing them to the normalizer","Pin/monitor Zhihu API response shape; alert on schema drift","Prefer skipping and logging bad rows in aggregation scripts rather than aborting the whole search","Keep stripHtml/itemKey/itemUrl unit-tested against real payload samples"],"tags":["zhihu","search","data-validation","api"],"backgroundTag":"malformed-api-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}