jackwener/OpenCLI · error · CommandExecutionError
Nowcoder ${source} returned malformed records
Error message
Nowcoder ${source} returned malformed records What it means
projectNowcoderFeed is the public entry point for normalizing Nowcoder feed responses into post rows. It requires the records argument to be a real array; anything else (null, an object, a string) is rejected with this error, which names the source ('recommend', 'experience', etc.) so you know which feed failed. It guards against passing raw response envelopes or undefined fetch results straight into projection.
Source
Thrown at clis/nowcoder/posts.js:167
const post = data.momentData;
const entityId = requiredId(post.id, 'moment entity id');
if ((requireOuterId || data.contentId != null) && entityId !== requiredId(data.contentId, 'moment feed id')) {
throw new CommandExecutionError('Nowcoder returned mismatched moment feed identity');
}
const uuid = requiredUuid(post.uuid, 'moment uuid');
return {
...commonFeedFields(data, post, 'moment', post.userId, post.createdAt, index),
id: uuid,
uuid,
entity_id: entityId,
url: `https://www.nowcoder.com/feed/main/detail/${uuid}`,
};
}
throw new CommandExecutionError(`Nowcoder returned unsupported feed contentType ${String(data.contentType)}`);
}
export function projectNowcoderFeed(records, limit, source, wrapped = false) {
if (!Array.isArray(records)) throw new CommandExecutionError(`Nowcoder ${source} returned malformed records`);
const rows = [];
for (const record of records) {
const data = wrapped ? record?.data : record;
rows.push(projectFeedData(data, rows.length, source === 'experience' || wrapped));
}
if (rows.length === 0) throw new EmptyResultError(`nowcoder ${source}`, 'Nowcoder returned no content or moment posts.');
return rows.slice(0, limit);
}
export function parseNowcoderPostTarget(raw) {
const value = typeof raw === 'string' ? raw.trim() : '';
if (NUMERIC_ID_PATTERN.test(value)) return { post_type: 'content', value };
if (UUID_PATTERN.test(value)) return { post_type: 'moment', value: value.toLowerCase() };
let url;
try {
url = new URL(value);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Locate the correct array in the response (e.g., payload.data.records or payload.data.feed.list) and pass that to projectNowcoderFeed.
- Use fetchNowcoderData to validate the envelope first, then pick the array field it returns.
- Add a console.log/Object.keys inspection of the response object to find where the list now lives.
- If you must tolerate missing data, check Array.isArray before calling and surface your own error.
Example fix
// before const rows = projectNowcoderFeed(payload, 10, 'recommend'); // after const rows = projectNowcoderFeed(payload.data.feed.records, 10, 'recommend');
Defensive patterns
Strategy: validation
Validate before calling
if (!Array.isArray(records)) throw new TypeError(`expected feed records array, got ${typeof records}`);
const rows = projectNowcoderFeed(records, limit, source, wrapped); Type guard
function isFeedRecords(value) { return Array.isArray(value); } Try / catch
try {
rows = projectNowcoderFeed(records, limit, source, wrapped);
} catch (error) {
if (String(error.message).includes('returned malformed records')) {
throw new Error(`Feed source '${source}' did not yield an array; inspect the response shape`);
}
throw error;
} Prevention
- Pass the array member of the response (e.g., payload.data.records), not the envelope
- Validate the envelope with fetchNowcoderData before projecting
- Assert Array.isArray on integration boundaries in tests
- Check for null/undefined fetch results before piping into projection
When it happens
Trigger: Calling projectNowcoderFeed(records, limit, source) where records is not an Array — typically the payload.data field of a response was passed instead of its array member (e.g., data.feed.records), or a fetch returned null/undefined.
Common situations: Extracting the wrong key from the Nowcoder JSON envelope after an API change; passing the whole {success, code, data} object instead of data's inner list; a fetch helper returning undefined on error being piped directly into projection.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Nowcoder returned a malformed feed row
- Nowcoder returned mismatched content feed data
- Nowcoder returned mismatched moment feed data
- Nowcoder returned unsupported feed contentType ${String(data
- <train-no> must not be empty
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/bfee243a27dc7330.
Report an issue: GitHub.