jackwener/OpenCLI · error · CommandExecutionError
${commandName}: malformed comment row image URL
Error message
${commandName}: malformed comment row image URL What it means
Each entry in a comment row's images array must be a string URL. A non-string element (number, object, null item) throws this CommandExecutionError because the URL cannot be parsed safely.
Source
Thrown at clis/xiaohongshu/comments.js:85
function normalizeOptionalString(value, field, commandName) {
if (value == null)
return '';
if (typeof value !== 'string') {
throw new CommandExecutionError(`${commandName}: malformed comment row ${field}`);
}
return value;
}
export function normalizeCommentImages(value, commandName) {
if (value == null)
return [];
if (!Array.isArray(value)) {
throw new CommandExecutionError(`${commandName}: malformed comment row images`);
}
const urls = [];
for (const raw of value) {
if (typeof raw !== 'string') {
throw new CommandExecutionError(`${commandName}: malformed comment row image URL`);
}
const trimmed = raw.trim();
let parsed;
try {
parsed = new URL(trimmed);
}
catch {
throw new CommandExecutionError(`${commandName}: malformed comment row image URL`);
}
if ((parsed.protocol !== 'https:' && parsed.protocol !== 'http:') || parsed.username || parsed.password) {
throw new CommandExecutionError(`${commandName}: malformed comment row image URL`);
}
const href = parsed.toString();
if (!urls.includes(href))
urls.push(href);
}
return urls;
}View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect the array element that is not a string and map it to its url property before normalizing.
- Add a pre-parse step converting image objects to their URL strings.
- Update normalizeCommentImages to accept {url}-style objects.
- Validate each element with typeof === 'string' before calling the API.
Example fix
// before normalizeCommentImages(row.images, cmd); // after const imgs = (row.images ?? []).map(i => typeof i === 'string' ? i : i?.url); normalizeCommentImages(imgs, cmd);
Defensive patterns
Strategy: type-guard
Validate before calling
const bad = (row.images ?? []).filter(i => typeof i !== 'string');
if (bad.length) throw new Error(`${bad.length} non-string image entries`); Type guard
function isStringArray(v) {
return Array.isArray(v) && v.every(x => typeof x === 'string');
} Try / catch
try {
urls = normalizeCommentImages(row.images, cmd);
} catch (e) {
if (e instanceof CommandExecutionError && /image URL/.test(e.message)) {
urls = [];
} else throw e;
} Prevention
- Map structured image objects to their url string before normalizing.
- Filter non-string entries out of scraped image arrays.
- Log the offending element (index/type) when this fires.
- Keep extraction code returning plain URL strings, not descriptors.
When it happens
Trigger: The images array contains a non-string element, e.g. an image descriptor object { url, width } instead of the plain URL string.
Common situations: XHS payload drift to structured image objects, or caller mapping rows incorrectly and pushing objects into the images array.
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
- ${label} returned an unexpected payload shape; expected an o
- ${label} returned an unexpected payload shape; expected an a
- ${label} did not include a stable ${field}.
- archive wayback returned malformed payload: closest snapshot
- Barchart greeks returned a malformed option row identity
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/af906e684701ec16.
Report an issue: GitHub.