jackwener/OpenCLI · error · CommandExecutionError
Nowcoder returned mismatched content feed identity
Error message
Nowcoder returned mismatched content feed identity
What it means
For content-type feed rows, the inner post id must match the outer row's contentId whenever the outer id is required (experience source or wrapped mode) or present. This error means contentData.id and data.contentId disagree, indicating the feed row's payload does not correspond to the id Nowcoder advertised at the envelope level, so the library treats it as inconsistent data.
Source
Thrown at clis/nowcoder/posts.js:134
...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');
}
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');View on GitHub (pinned to 49907e53dc)
Solutions
- Check data.contentId vs post.id on the offending row to confirm which id is authoritative.
- If the source does not guarantee outer ids, avoid forcing requireOuterId (don't pass source='experience' or wrapped=true unnecessarily).
- Pre-filter rows where contentData.id !== contentId before projection.
- Re-fetch the feed; if it reproduces consistently, Nowcoder changed envelope semantics and the code must be updated.
Example fix
// before rows.push(projectFeedData(data, rows.length, true)); // forces outer id check // after const consistent = data.contentId == null || String(data.contentData?.id) === String(data.contentId); if (consistent) rows.push(projectFeedData(data, rows.length, true));
Defensive patterns
Strategy: validation
Validate before calling
const idsMatch = (d) => d?.contentId == null || String(d?.contentData?.id) === String(d.contentId);
const usable = records.filter((r) => { const d = wrapped ? r?.data : r; return d?.contentType !== 250 || idsMatch(d); }); Type guard
function hasConsistentContentIdentity(d) { return isRecord(d) && (d.contentId == null || String(d.contentData?.id) === String(d.contentId)); } Try / catch
try {
rows = projectNowcoderFeed(records, limit, source, wrapped);
} catch (error) {
if (String(error.message).includes('mismatched content feed identity')) {
rows = projectNowcoderFeed(records.filter((r) => hasConsistentContentIdentity(wrapped ? r?.data : r)), limit, source, wrapped);
} else throw error;
} Prevention
- Only force outer-id checks (wrapped/source='experience') when the API actually guarantees contentId
- Pre-filter rows where contentData.id !== contentId
- Do not mix rows cached from different requests
- Re-fetch the feed if a single row fails — it may be transient
When it happens
Trigger: A contentType-250 row where (requireOuterId || data.contentId != null) and requiredId(post.id) !== requiredId(data.contentId) — i.e., inner content id differs from the outer contentId (or contentId is absent when required).
Common situations: Nowcoder reuses feed envelopes for recommended/related items whose outer id points elsewhere; experience feed returns wrapped rows without contentId; caching mixed rows from different requests; upstream id reassignment after post edits.
Related errors
- Nowcoder returned mismatched moment feed identity
- Bilibili creator comparison returned a malformed manuscript
- Bilibili creator comparison returned duplicate rows for ${bv
- Bilibili view API returned duplicate page entries for p=${pa
- Booking.com hotel row is missing stable name/url identity
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/e395973dd53e7020.
Report an issue: GitHub.