jackwener/OpenCLI · error · CommandExecutionError

Nowcoder returned mismatched ${label} authorship

Error message

Nowcoder returned mismatched ${label} authorship

What it means

After extracting the author id from userBrief.userId, authorFields() cross-checks it against the id provided at the feed/detail level (contentData.authorId for content posts, momentData.userId for moments, or detail-level ids). This error means the two id sources disagree — the payload's author block belongs to a different user than the post's declared author, indicating inconsistent or tampered data.

Source

Thrown at clis/nowcoder/posts.js:101

}

function isoTime(value, label) {
    if (!Number.isSafeInteger(value) || value <= 0) throw new CommandExecutionError(`Nowcoder returned a malformed ${label}`);
    const date = new Date(value);
    if (Number.isNaN(date.getTime())) throw new CommandExecutionError(`Nowcoder returned a malformed ${label}`);
    return date.toISOString();
}

function metric(frequency, key) {
    const value = frequency[key];
    if (!Number.isSafeInteger(value) || value < 0) throw new CommandExecutionError(`Nowcoder returned a malformed frequencyData.${key}`);
    return value;
}

function authorFields(userBrief, expectedId, label) {
    if (!isRecord(userBrief)) throw new CommandExecutionError(`Nowcoder returned malformed ${label} authorship`);
    const authorId = requiredId(userBrief.userId, `${label} userBrief.userId`);
    if (authorId !== requiredId(expectedId, `${label} author id`)) throw new CommandExecutionError(`Nowcoder returned mismatched ${label} authorship`);
    return {
        author: optionalText(userBrief.nickname, `${label} author nickname`),
        author_id: authorId,
        author_url: `https://www.nowcoder.com/users/${authorId}`,
        school: optionalText(userBrief.educationInfo, `${label} author education`),
    };
}

function commonFeedFields(data, post, postType, authorId, timestamp, index) {
    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'),

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log both ids (post-level authorId/userId and userBrief.userId) for the failing item and compare
  2. If Nowcoder changed the semantics of one field, update the library to compare against the correct source
  3. Test with a different post to determine whether it's item-specific corruption or an API-wide change
  4. Clear any cached/proxied responses and re-fetch; stale caches can mix old and new author fields

Example fix

// before (payload changed: userId now the reposter)
...authorFields(data.userBrief, post.userId, 'moment')
// after (use the original-author field)
...authorFields(data.userBrief, post.originalUserId ?? post.userId, 'moment')
Defensive patterns

Strategy: validation

Validate before calling

function authorshipConsistent(data) {
  const briefId = data?.userBrief?.userId;
  const outerId = data?.contentData?.authorId ?? data?.momentData?.userId;
  return String(briefId) === String(outerId);
}
// pre-check rows before projecting

Type guard

function hasMatchingAuthorIds(data) {
  const a = data?.userBrief?.userId;
  const b = data?.contentData?.authorId ?? data?.momentData?.userId;
  return a != null && b != null && String(a) === String(b);
}

Try / catch

try {
  const rows = projectNowcoderFeed(records, limit, source);
} catch (err) {
  if (err instanceof CommandExecutionError && /mismatched .* authorship/.test(err.message)) {
    // re-fetch the item fresh (cache may be stale) or flag for manual review
  } else throw err;
}

Prevention

When it happens

Trigger: contentData.authorId ≠ data.userBrief.userId, or momentData.userId ≠ data.userBrief.userId, in a feed row; in projectNowcoderDetail, data.authorId/data.userId disagrees with data.userBrief.userId. Usually one of the two fields was renamed, defaulted, or points to a reposter/last-editor rather than the original author.

Common situations: Nowcoder changes which field carries the author id (e.g. authorId now holds an editor id); shared/reposted moments where userBrief reflects the sharer; partially refreshed cache returning stale userBrief with a new authorId; malformed mock/test fixtures.

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.

Related errors


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