jackwener/OpenCLI · error · CommandExecutionError

Nowcoder returned mismatched content feed data

Error message

Nowcoder returned mismatched content feed data

What it means

When a feed row declares contentType 250 (content/discuss post), projectFeedData requires contentData to be a record, momentData to be absent, and contentData.entityType to equal 8. This error means the row's type marker says 'content' but its payload does not match that shape, so the library refuses to project it rather than produce a half-populated post.

Source

Thrown at clis/nowcoder/posts.js:129

    if (!isRecord(data.frequencyData)) throw new CommandExecutionError(`Nowcoder returned malformed ${postType} frequencyData`);
    return {
        rank: index + 1,
        post_type: postType,
        title: optionalText(post.title, `${postType} title`) || '(untitled)',
        ...authorFields(data.userBrief, authorId, postType),
        content: cleanBody(post.content, `${postType} content`),
        likes: metric(data.frequencyData, 'likeCnt'),
        comments: metric(data.frequencyData, 'commentCnt'),
        views: metric(data.frequencyData, 'viewCnt'),
        time: isoTime(timestamp, `${postType} timestamp`),
    };
}

function projectFeedData(data, index, requireOuterId) {
    if (!isRecord(data)) throw new CommandExecutionError('Nowcoder returned a malformed feed row');
    if (data.contentType === CONTENT_FEED_TYPE) {
        if (!isRecord(data.contentData) || data.momentData != null || data.contentData.entityType !== CONTENT_ENTITY_TYPE) {
            throw new CommandExecutionError('Nowcoder returned mismatched content feed data');
        }
        const post = data.contentData;
        const id = requiredId(post.id, 'content id');
        if ((requireOuterId || data.contentId != null) && id !== requiredId(data.contentId, 'content feed id')) {
            throw new CommandExecutionError('Nowcoder returned mismatched content feed identity');
        }
        const uuid = requiredUuid(post.uuid, 'content uuid');
        return {
            ...commonFeedFields(data, post, 'content', post.authorId, post.createTime, index),
            id,
            uuid,
            entity_id: requiredId(post.entityId, 'content entity id'),
            url: `https://www.nowcoder.com/discuss/${id}`,
        };
    }
    if (data.contentType === MOMENT_TYPE) {
        if (!isRecord(data.momentData) || data.contentData != null) {
            throw new CommandExecutionError('Nowcoder returned mismatched moment feed data');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Inspect the offending row's contentData and entityType to see what shape Nowcoder actually returned.
  2. Skip such rows by pre-filtering records before calling projectNowcoderFeed.
  3. Update CONTENT_ENTITY_TYPE or the projection logic if Nowcoder changed the entity type constant.
  4. Retry the feed request — transient partial payloads may resolve on a fresh fetch.

Example fix

// before
const rows = projectNowcoderFeed(records, 10, 'recommend');
// after
const valid = records.filter((r) => r?.data?.contentType !== 250 || r?.data?.contentData?.entityType === 8);
const rows = projectNowcoderFeed(valid, 10, 'recommend');
Defensive patterns

Strategy: validation

Validate before calling

const isContentRow = (d) => isRecord(d) && d.contentType === 250 && isRecord(d.contentData) && d.momentData == null && d.contentData.entityType === 8;
records = records.filter((r) => { const d = wrapped ? r?.data : r; return d == null || isContentRow(d) || d.contentType !== 250; });

Type guard

function isProjectableContentRow(d) { return isRecord(d) && d.contentType === 250 && isRecord(d.contentData) && d.momentData == null && d.contentData.entityType === 8; }

Try / catch

try {
    rows = projectNowcoderFeed(records, limit, source, wrapped);
} catch (error) {
    if (String(error.message).includes('mismatched content feed data')) {
        console.error('Nowcoder content row shape changed; inspect contentData/entityType');
    }
    throw error;
}

Prevention

When it happens

Trigger: A feed row with contentType===250 arrives where contentData is missing/null/not an object, momentData is also present, or contentData.entityType !== 8.

Common situations: Nowcoder A/B-testing new feed payloads; pinned/advertised rows that reuse contentType 250 with a different entity type; partial API responses after upstream errors; stale assumptions after a Nowcoder API version change.

Related errors


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