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

  1. Locate the correct array in the response (e.g., payload.data.records or payload.data.feed.list) and pass that to projectNowcoderFeed.
  2. Use fetchNowcoderData to validate the envelope first, then pick the array field it returns.
  3. Add a console.log/Object.keys inspection of the response object to find where the list now lives.
  4. 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

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.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/bfee243a27dc7330. Report an issue: GitHub.