jackwener/OpenCLI · error · CommandExecutionError

Nowcoder returned a malformed frequencyData.${key}

Error message

Nowcoder returned a malformed frequencyData.${key}

What it means

metric() reads a counter (likeCnt, commentCnt, viewCnt) from data.frequencyData and requires a non-negative safe integer. This error means the engagement-count field named in the message is missing, null, a float, negative, or a non-numeric type in the Nowcoder payload — the library refuses to invent default counts.

Source

Thrown at clis/nowcoder/posts.js:94

        .split('\n')
        .map((line) => line.replace(/[\t ]+/g, ' ').trim())
        .join('\n')
        .replace(/^\s+|\s+$/g, '')
        .replace(/\n{3,}/g, '\n\n');
    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 {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log data.frequencyData for the failing item and compare its keys to likeCnt/commentCnt/viewCnt
  2. If fields were renamed, update the library or map the new names before calling
  3. Coerce string counts with Number(value) in wrapper code when the payload returns stringified integers
  4. Skip or default-count items whose frequencyData lacks the fields (only in your own pre-processing)

Example fix

// before
const likes = data.frequencyData.likeCnt; // now 'likeCount'
// after
const likes = data.frequencyData.likeCnt ?? data.frequencyData.likeCount;
Defensive patterns

Strategy: validation

Validate before calling

const REQUIRED_METRICS = ['likeCnt', 'commentCnt', 'viewCnt'];
function hasValidFrequency(data) {
  const f = data?.frequencyData;
  return Boolean(f) && typeof f === 'object' && !Array.isArray(f)
    && REQUIRED_METRICS.every(k => Number.isSafeInteger(f[k]) && f[k] >= 0);
}

Type guard

function isFrequencyData(value) {
  return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
    && ['likeCnt','commentCnt','viewCnt'].every(k => Number.isSafeInteger(value[k]) && value[k] >= 0);
}

Try / catch

try {
  const rows = projectNowcoderFeed(records, limit, source);
} catch (err) {
  if (err instanceof CommandExecutionError && /frequencyData\./.test(err.message)) {
    const key = err.message.match(/frequencyData\.(\w+)/)?.[1];
    // remap renamed metric key or skip the row
  } else throw err;
}

Prevention

When it happens

Trigger: data.frequencyData.likeCnt/commentCnt/viewCnt is undefined (field renamed or dropped), a string like '12', a float, or -1 in a feed row (commonFeedFields) or detail payload (projectNowcoderDetail).

Common situations: Nowcoder renames counters (e.g. likeCnt → likeCount); newly created posts omit count fields entirely; API A/B tests return string counts; region-localized payloads format numbers as strings.

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