jackwener/OpenCLI · error · CommandExecutionError
toutiao recommend returned message=${payload.message}
Error message
toutiao recommend returned message=${payload.message} What it means
This CommandExecutionError is thrown when the toutiao recommend payload contains a message field whose value is not 'success'. The upstream API signals business-level failures inside a 200 JSON body via this message field, and the library surfaces it verbatim.
Source
Thrown at clis/toutiao/recommend.js:61
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
Accept: 'application/json',
Referer: 'https://www.toutiao.com/',
},
});
} catch (error) {
throw new CommandExecutionError(`toutiao recommend request failed: ${error?.message || error}`);
}
if (!resp.ok) {
throw new CommandExecutionError(`toutiao recommend failed: HTTP ${resp.status}`);
}
let payload;
try {
payload = await resp.json();
} catch (error) {
throw new CommandExecutionError(`toutiao recommend returned malformed JSON: ${error?.message || error}`);
}
if (payload?.message && payload.message !== 'success') {
throw new CommandExecutionError(`toutiao recommend returned message=${payload.message}`);
}
if (!Array.isArray(payload?.data)) {
throw new CommandExecutionError('toutiao recommend returned a non-array data field');
}
const rows = payload.data.map(mapRecommendRow).filter(Boolean).slice(0, limit);
if (rows.length === 0) {
throw new EmptyResultError('toutiao recommend', `频道 ${category} 返回空列表。`);
}
// Re-rank (1..N) after filter so ranks are dense even if upstream had ads.
return rows.map((row, idx) => ({ ...row, rank: idx + 1 }));
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Read the embedded message value to learn what upstream rejected (it is printed verbatim in the error).
- Slow down request rate and add cookies/headers if the message indicates risk control or frequency limits.
- If upstream legitimately changed its success marker, update the `payload.message !== 'success'` check in recommend.js to match the new contract.
- Retry later if the message indicates a temporary upstream condition.
Defensive patterns
Strategy: try-catch
Try / catch
try {
return await recommend({ category });
} catch (e) {
const m = /returned message=(.+)/.exec(e.message);
if (m) {
console.error('Upstream business error:', m[1]);
return []; // degrade gracefully
}
throw e;
} Prevention
- Surface the embedded message verbatim when logging — it names the upstream rejection reason.
- Slow down and add cookies if messages indicate risk control.
- Watch for new message values after upstream API updates.
- Pin library versions and read changelogs for upstream contract changes.
When it happens
Trigger: Calling 'toutiao recommend' when the parsed JSON has payload.message set to anything other than 'success' — e.g. risk-control rejections, quota/permission errors, or other upstream business errors.
Common situations: Toutiao risk-control flagging the request as automated; API contract change introducing a new message value the check does not recognize; regional restrictions reported via message instead of HTTP status.
Related errors
- toutiao recommend returned a non-array data field
- No prices returned for train_no=${trainNo} ${fromStation.nam
- 12306 queryByTrainNo returned HTTP ${resp.status}
- 12306 queryByTrainNo returned non-JSON body
- Bilibili creator comparison API returned a malformed envelop
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/ef3d2fb6be1e39eb.
Report an issue: GitHub.