{"record":{"id":"395b9245c6fe54a9","repo":"jackwener/OpenCLI","slug":"zhihu-collection-returned-a-malformed-item-without","errorCode":null,"errorMessage":"Zhihu collection returned a malformed item without title or URL identity","messagePattern":"Zhihu collection returned a malformed item without title or URL identity","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/zhihu/collection.js","lineNumber":88,"sourceCode":"    url = content.url || `https://www.zhihu.com/question/${question.id}/answer/${content.id}`;\n    author = content.author?.name || '匿名用户';\n    votes = content.voteup_count || 0;\n  } else if (type === 'article') {\n    title = content.title || '';\n    excerpt = stripHtml(content.content || '').substring(0, 150);\n    url = content.url || `https://zhuanlan.zhihu.com/p/${content.id}`;\n    author = content.author?.name || '匿名用户';\n    votes = content.voteup_count || 0;\n  } else if (type === 'pin') {\n    title = '想法';\n    excerpt = stripHtml((content.content || []).map((c) => c.content || '').join(' ')).substring(0, 150);\n    url = content.url || `https://www.zhihu.com/pin/${content.id}`;\n    author = content.author?.name || '匿名用户';\n    votes = content.reaction_count || 0;\n  }\n\n  if (!String(title || '').trim() || !String(url || '').trim() || url.includes('undefined')) {\n    throw new CommandExecutionError(\n      'Zhihu collection returned a malformed item without title or URL identity',\n      'Collection item rows require type, title, and URL so malformed payloads do not become blank listing rows.',\n    );\n  }\n\n  return {\n    rank,\n    type,\n    title: stripHtml(title).substring(0, 100),\n    author,\n    votes,\n    excerpt,\n    url,\n  };\n}\n\ncli({\n  site: 'zhihu',","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/zhihu/collection.js#L70-L106","documentation":"mapCollectionItem throws CommandExecutionError when a mapped collection item ends up with an empty title, an empty URL, or a URL containing 'undefined'. This guards against Zhihu returning items whose identity fields are missing, which would otherwise render as blank/broken listing rows.","triggerScenarios":"A collection item's content lacks title and its derived URL is empty or was built from a missing content.id (producing 'https://www.zhihu.com/pin/undefined'), typically because Zhihu's payload was truncated, redacted for unauthenticated views, or the item was deleted.","commonSituations":"Fetching a collection while partially logged out so Zhihu strips fields; deleted or shadow-banned content still listed in the collection; API returning partial items under anti-crawler degradation.","solutions":["Re-authenticate so Zhihu returns full item payloads, then retry","Update the CLI in case a newer mapper handles the new payload shape","Retry later — often a transient degraded API response","Log the raw item (with -v) and report a schema-drift bug if it reproduces"],"exampleFix":"// before\n// mapper throws on blank title/url\n// after\nconst items = raw.filter(it => it.content && it.content.title && it.content.id); // pre-filter malformed items before mapping","handlingStrategy":"validation","validationCode":"const usable = rawItems.filter(it => {\n  const t = String(it?.content?.title ?? it?.title ?? '').trim();\n  const u = String(it?.content?.url ?? it?.url ?? '');\n  return t && u && !u.includes('undefined');\n});","typeGuard":"function hasItemIdentity(item) {\n  const title = String(item?.content?.title ?? '').trim();\n  const url = String(item?.content?.url ?? '').trim();\n  return Boolean(title) && Boolean(url) && !url.includes('undefined');\n}","tryCatchPattern":"try {\n  return rawItems.map(mapCollectionItem);\n} catch (e) {\n  if (e.message.includes('malformed item')) return rawItems.filter(hasItemIdentity).map(mapCollectionItem);\n  throw e;\n}","preventionTips":["Pre-filter items lacking title/url/id before mapping","Ensure full authentication so Zhihu does not redact fields","Treat 'undefined' in any URL as a signal of a missing id upstream","Log dropped items for later inspection rather than silently ignoring"],"tags":["validation","zhihu","schema","data-quality"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}