jackwener/OpenCLI · error · CommandExecutionError
xiaohongshu creator-note-detail: signed API ${suffix} return
Error message
xiaohongshu creator-note-detail: signed API ${suffix} returned malformed ${key} What it means
assertOptionalArray guards optional fields in a captured signed-API payload: if a key is present it must be an array. When the creator-platform endpoint returns a field like hour/day/stats that exists but is not an array (object, string, null-shaped), the command rejects the payload as malformed.
Source
Thrown at clis/xiaohongshu/creator-note-detail.js:273
if (!url)
return null;
try {
const parsed = new URL(String(url), 'https://creator.xiaohongshu.com');
return DETAIL_API_ENDPOINTS.find((endpoint) => parsed.pathname === endpoint.suffix) ?? null;
}
catch {
return null;
}
}
function findCapturedUrl(captureMap, suffix) {
return Object.keys(captureMap).find((url) => detailApiEndpointForUrl(url)?.suffix === suffix);
}
function isPlainObject(value) {
return value !== null && typeof value === 'object' && !Array.isArray(value);
}
function assertOptionalArray(payload, key, suffix) {
if (key in payload && !Array.isArray(payload[key])) {
throw new CommandExecutionError(`xiaohongshu creator-note-detail: signed API ${suffix} returned malformed ${key}`);
}
}
function assertOptionalPlainObject(payload, key, suffix) {
if (key in payload && !isPlainObject(payload[key])) {
throw new CommandExecutionError(`xiaohongshu creator-note-detail: signed API ${suffix} returned malformed ${key}`);
}
}
function validateCapturedPayload(payload, endpoint) {
const suffix = endpoint.suffix;
if (!isPlainObject(payload)) {
throw new CommandExecutionError(`xiaohongshu creator-note-detail: signed API ${suffix} returned a malformed payload`);
}
if (endpoint.key === 'noteBase') {
assertOptionalPlainObject(payload, 'hour', suffix);
assertOptionalPlainObject(payload, 'day', suffix);
}
if (endpoint.key === 'audienceSource') {
assertOptionalArray(payload, 'source', suffix);View on GitHub (pinned to 49907e53dc)
Solutions
- Dump the raw capture.body for the failing suffix and compare the field's actual shape against the expected array
- Handle the alternative shape (e.g. convert object-of-days to an array) before validation
- Update validateCapturedPayload/assertOptionalArray to accept the new API shape
- Check API/account permissions — a degraded response may accompany permission or plan changes
Example fix
// before
if (key in payload && !Array.isArray(payload[key])) {
throw new CommandExecutionError(`... returned malformed ${key}`);
}
// after
if (key in payload && !Array.isArray(payload[key])) {
const v = payload[key];
if (v && typeof v === 'object' && !Array.isArray(v)) {
payload[key] = Object.values(v); // coerce object-of-values to array
} else {
throw new CommandExecutionError(`... returned malformed ${key}`);
}
} Defensive patterns
Strategy: type-guard
Validate before calling
const isArr = (payload, key) => !(key in payload) || Array.isArray(payload[key]);
if (!isArr(payload, 'hour') || !isArr(payload, 'day')) throw new Error('unexpected stats shape'); Type guard
const isOptionalArray = (obj, key) => !(key in obj) || Array.isArray(obj[key]);
Try / catch
try {
const detail = await cli.creatorNoteDetail(noteId);
} catch (err) {
if (err.message.includes('returned malformed')) {
// log raw capture.body and degrade gracefully (skip stats)
} else throw err;
} Prevention
- Snapshot real API responses and validate shapes in CI
- Handle object-vs-array stats shapes defensively
- Check account analytics permissions before querying
- Watch for creator API version changes
When it happens
Trigger: validateCapturedPayload calls assertOptionalArray for a key (e.g. on audienceSource or noteBase-derived endpoints) and payload[key] is present but Array.isArray fails — typically an error object or nested object returned instead of a list.
Common situations: Xiaohongshu creator API changed the field shape (object keyed by date instead of array); API returned an error body that still parsed as JSON; account lacks analytics permission so the endpoint returns a different structure.
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
- xiaohongshu creator-note-detail: signed API ${suffix} return
- Bilibili comments reply ${index + 1} was malformed
- 获取到的视频播放信息对象不符合预期格式
- Bilibili conclusion API returned malformed model_result JSON
- Bilibili conclusion API returned malformed model_result
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/1b5f8d4f53723bd6.
Report an issue: GitHub.