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
- Log data.frequencyData for the failing item and compare its keys to likeCnt/commentCnt/viewCnt
- If fields were renamed, update the library or map the new names before calling
- Coerce string counts with Number(value) in wrapper code when the payload returns stringified integers
- 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
- Check likeCnt/commentCnt/viewCnt names after each Nowcoder API update
- Coerce stringified counts with Number() when the API returns strings
- Skip or default rows whose frequencyData lacks metrics (in your own preprocessing)
- Compare frequencyData keys against a known-good captured payload when errors spike
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Nowcoder returned malformed ${postType} frequencyData
- Nowcoder returned a malformed ${label}
- Nowcoder returned malformed ${label} authorship
- Bilibili ${label} API returned malformed top_replies
- Bilibili creator comparison returned malformed stat data for
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/d57d581e22ff94df.
Report an issue: GitHub.