jackwener/OpenCLI · error · CommandExecutionError
Zhihu search returned malformed result row identity
Error message
Zhihu search returned malformed result row identity
What it means
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.
Source
Thrown at clis/zhihu/search.js:110
}
if (!payload.paging || typeof payload.paging !== 'object') {
throw new CommandExecutionError('Zhihu search returned malformed paging data', `URL: ${url}`);
}
return payload;
}
function normalizeResultItem(item) {
if (!item || typeof item !== 'object' || item.type !== 'search_result' || !item.object || typeof item.object !== 'object') {
return null;
}
const obj = item.object;
if (obj.type !== 'answer' && obj.type !== 'article' && obj.type !== 'question') return null;
const key = itemKey(item);
const url = itemUrl(obj);
const question = obj.question || {};
const title = stripHtml(obj.title || question.name || question.title || '');
if (!key || !url || !title) {
throw new CommandExecutionError('Zhihu search returned malformed result row identity');
}
return {
item,
key,
row: {
title,
type: obj.type,
author: obj.author?.name || '',
votes: obj.voteup_count || 0,
url,
},
};
}
cli({
site: 'zhihu',
name: 'search',
access: 'read',View on GitHub (pinned to 49907e53dc)
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
Example fix
// before
if (!key || !url || !title) {
throw new CommandExecutionError('Zhihu search returned malformed result row identity');
}
// after
if (!key || !url || !title) {
console.warn('skipping malformed row', item);
return null;
} Defensive patterns
Strategy: validation
Validate before calling
function isUsableRow(item) {
const t = item?.target;
return t && ['answer','article','question'].includes(t.type) &&
!!t.id && !!(t.title || t.question?.title || t.question?.name);
}
const usable = (data.data || []).filter(isUsableRow); Type guard
function hasRowIdentity(obj) {
return typeof obj === 'object' && obj !== null &&
typeof obj.type === 'string' &&
['answer','article','question'].includes(obj.type) &&
typeof obj.title === 'string' && obj.title.trim() !== '' &&
typeof obj.url === 'string' && obj.url !== '';
} Try / catch
try {
const results = await zhihuSearch(query, opts);
} catch (err) {
if (err.message.includes('malformed result row identity')) {
console.error('Zhihu API returned an unidentifiable row; retry or inspect raw payload', err);
} else throw err;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
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
- Zhihu answer comments contained a ${role} row without a stab
- Zhihu answer comment ${id} did not identify its immediate pa
- Zhihu answer root comment ${id} had malformed child count
- Zhihu search pagination returned malformed next URL
- Zhihu user answers returned malformed row identity
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/047c18a98a5a8346.
Report an issue: GitHub.