jackwener/OpenCLI · error · CommandExecutionError
Unexpected Xiaohongshu search harvest row ${index + 1} shape
Error message
Unexpected Xiaohongshu search harvest row ${index + 1} shape; expected string ${field}. What it means
Each harvest row must contain string values for the fields title, author, likes, url, and author_url. When row[field] is not a string (missing, null, number, object), the CLI rejects the row because every consumer expects strings (likes is kept as its displayed string).
Source
Thrown at clis/xiaohongshu/search.js:297
if (url === '')
return true;
try {
const parsed = new URL(url);
return parsed.protocol === 'https:' &&
parsed.hostname.toLowerCase() === webHost.toLowerCase() &&
/^\/user\/profile\/[^/]+\/?$/i.test(parsed.pathname);
}
catch {
return false;
}
}
function requireTrustedHarvestRow(row, index, webHost) {
if (!row || typeof row !== 'object' || Array.isArray(row)) {
throw new CommandExecutionError(`Unexpected Xiaohongshu search harvest row ${index + 1} shape; expected an object.`);
}
for (const field of ['title', 'author', 'likes', 'url', 'author_url']) {
if (typeof row[field] !== 'string') {
throw new CommandExecutionError(`Unexpected Xiaohongshu search harvest row ${index + 1} shape; expected string ${field}.`);
}
}
if (!noteUrlInfo(row.url, webHost).key) {
throw new CommandExecutionError(`Unexpected Xiaohongshu search harvest row ${index + 1} URL; expected a trusted note URL.`);
}
if (!isTrustedAuthorUrl(row.author_url, webHost)) {
throw new CommandExecutionError(`Unexpected Xiaohongshu search harvest row ${index + 1} author URL; expected a trusted profile URL.`);
}
return row;
}
function requireHarvestPayload(payload, webHost) {
const result = unwrapEvaluateResult(payload);
const diag = result?.diag;
if (!result || typeof result !== 'object' || Array.isArray(result) || !Array.isArray(result.rows) ||
!diag || typeof diag !== 'object' || Array.isArray(diag) ||
typeof diag.securityBlock !== 'boolean' || typeof diag.stopReason !== 'string' ||
!Number.isFinite(diag.scrollHeight) || diag.scrollHeight < 0 ||
!Number.isFinite(diag.clientHeight) || diag.clientHeight < 0 ||View on GitHub (pinned to 49907e53dc)
Solutions
- Re-run the search to rule out a partially rendered page.
- Update the CLI if xiaohongshu changed the card DOM so fields extract as null.
- Filter or treat ad/promoted cards differently — they often lack expected fields.
- Report persistent missing-field rows with the row contents for a harvest-script fix.
Defensive patterns
Strategy: type-guard
Type guard
function hasRequiredStringFields(row) {
return ['title','author','likes','url','author_url']
.every(f => typeof row?.[f] === 'string');
} Try / catch
try {
const rows = await searchNotes(query);
} catch (e) {
if (/expected string \w+/.test(String(e.message))) {
console.error('A result card lacked a field; retry or reduce result count:', e.message);
return searchNotes(query, { limit: smaller });
}
throw e;
} Prevention
- Retry with a smaller result set to skip ad/promoted cards that often lack fields.
- Re-run the search to rule out partially rendered pages.
- Update the CLI if the card DOM changed so fields extract as null.
- Note that likes is expected as a string, not a number, when pre-processing results.
When it happens
Trigger: A harvested row object at index+1 is missing one of the five required fields or has a non-string value — typically because the page node the script read was absent (e.g. no author element, hidden likes) so the script produced null/undefined.
Common situations: Search results with unusual card layouts (ads, video cards) lacking an author or likes element, DOM changes renaming classes, or partially-rendered results harvested before hydration finished.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Unexpected Xiaohongshu search harvest row ${index + 1} shape
- ${commandName}: malformed comment row ${field}
- ${commandName}: malformed comment row images
- ${commandName}: malformed comments payload
- ${commandName}: malformed comment row at index ${index}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b62c9d3445763c3d.
Report an issue: GitHub.