jackwener/OpenCLI · error · CommandExecutionError
${commandName}: malformed comment row likes
Error message
${commandName}: malformed comment row likes What it means
normalizeCommentRows requires each comment row to carry a non-negative integer likes count. It coerces row.likes with Number() and throws if the result is not an integer or is negative. This guarantees the normalized row shape consumed by the CLI output.
Source
Thrown at clis/xiaohongshu/comments.js:121
}
export function normalizeCommentRows(value, commandName = 'xiaohongshu/comments') {
if (value == null)
return [];
if (!Array.isArray(value)) {
throw new CommandExecutionError(`${commandName}: malformed comments payload`);
}
return value.map((row, index) => {
if (!row || typeof row !== 'object' || Array.isArray(row)) {
throw new CommandExecutionError(`${commandName}: malformed comment row at index ${index}`);
}
const text = normalizeOptionalString(row.text, 'text', commandName);
if (!text) {
throw new CommandExecutionError(`${commandName}: malformed comment row text`);
}
const likes = Number(row.likes);
if (!Number.isInteger(likes) || likes < 0) {
throw new CommandExecutionError(`${commandName}: malformed comment row likes`);
}
if (typeof row.is_reply !== 'boolean') {
throw new CommandExecutionError(`${commandName}: malformed comment row is_reply`);
}
return {
author: normalizeOptionalString(row.author, 'author', commandName),
authorHrefRaw: normalizeOptionalString(row.authorHrefRaw, 'authorHrefRaw', commandName),
text,
likes,
time: normalizeOptionalString(row.time, 'time', commandName),
is_reply: row.is_reply,
reply_to: normalizeOptionalString(row.reply_to, 'reply_to', commandName),
images: normalizeCommentImages(row.images, commandName),
};
});
}
/**View on GitHub (pinned to 49907e53dc)
Solutions
- Fix buildCommentsExtractJs to coerce like counts ('1.2k' -> 1200, missing -> 0) before returning rows
- Pre-validate the extractor output: ensure every row.likes is a non-negative integer
- Add a defensive default in normalizeCommentRows (treat missing likes as 0) if the shape permits
- Retry the scrape if the count element had not finished rendering
Example fix
// before
const likes = Number(row.likes);
// after
const rawLikes = String(row.likes ?? '').trim().toLowerCase();
const likes = /^\d+(\.\d+)?k$/.test(rawLikes)
? Math.round(parseFloat(rawLikes) * 1000)
: Number(rawLikes); Defensive patterns
Strategy: validation
Validate before calling
const toInt = v => { const n = Number(v); return Number.isInteger(n) && n >= 0 ? n : null; };
if (!rows.every(r => toInt(r.likes) !== null)) throw new Error('row.likes must be a non-negative integer'); Type guard
const hasValidLikes = (row) => { const n = Number(row.likes); return Number.isInteger(n) && n >= 0; }; Try / catch
try {
const comments = await cli.comments(noteUrl);
} catch (err) {
if (err.message.includes('malformed comment row likes')) {
// treat as extractor/DOM mismatch; retry or report
} else throw err;
} Prevention
- Coerce formatted counts ('1.2k') to integers inside the extractor
- Default missing like counts to 0 at extraction time
- Validate extractor output shape in tests
When it happens
Trigger: row.likes is undefined, null, a non-numeric string, a float, NaN, or a negative number such that Number(row.likes) fails the Number.isInteger/likes>=0 check.
Common situations: Xiaohongshu renders 'like' or '赞' instead of a number for zero-like comments so the extractor yields a non-numeric string; extractor grabs a formatted count like '1.2k'; DOM changes move the like-count element.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- ${commandName}: malformed comment row text
- ${commandName}: malformed comment row is_reply
- ${label} did not include a stable numeric id.
- ${label} did not include a stable text value.
- ${label} returned an unexpected payload shape; expected an o
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a1288df800fdd147.
Report an issue: GitHub.