jackwener/OpenCLI · error · CommandExecutionError

Nowcoder returned malformed ${label} authorship

Error message

Nowcoder returned malformed ${label} authorship

What it means

authorFields() expects data.userBrief to be a plain object containing the post author's profile summary. This throw fires when userBrief is missing, null, an array, or another non-object — the library cannot build author fields (author, author_id, author_url, school) and refuses to emit fabricated authorship data.

Source

Thrown at clis/nowcoder/posts.js:99

    for (const block of preBlocks) text = text.replace(block.token, block.text);
    return text;
}

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`),

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log the raw record and confirm whether userBrief exists for the failing item
  2. Retry with a valid logged-in Nowcoder session — degraded payloads often omit author data
  3. If Nowcoder moved the author block, remap the new field (e.g. data.author) to userBrief before calling, or update the library
  4. Filter out feed records without a userBrief object before projection

Example fix

// before
projectFeedData(record.data, i, true)
// after
if (!record?.data?.userBrief) continue; // skip rows with no author block
projectFeedData(record.data, i, true)
Defensive patterns

Strategy: type-guard

Validate before calling

function hasAuthorBrief(data) {
  return Boolean(data?.userBrief) && typeof data.userBrief === 'object' && !Array.isArray(data.userBrief);
}
// pre-filter: records.filter(r => hasAuthorBrief(r.data))

Type guard

function isUserBrief(value) {
  return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
    && (typeof value.userId === 'number' || typeof value.userId === 'string');
}

Try / catch

try {
  const rows = projectNowcoderFeed(records, limit, source);
} catch (err) {
  if (err instanceof CommandExecutionError && /malformed .* authorship/.test(err.message)) {
    // drop rows without a userBrief object or re-authenticate
  } else throw err;
}

Prevention

When it happens

Trigger: A feed row (commonFeedFields → authorFields) or detail payload (projectNowcoderDetail) has data.userBrief absent/null because Nowcoder omitted the author block — e.g. deleted accounts, anonymous or removed posts, or degraded unauthenticated responses.

Common situations: Author account deleted or banned after posting; scraping without a logged-in session returns rows without userBrief; API change nests author info elsewhere (e.g. data.authorInfo); ad/promoted entries lack real author objects.

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/1e6d0b631a08286f. Report an issue: GitHub.