jackwener/OpenCLI · error · Error
${d.msg || 'API failed'}
Error message
${d.msg || 'API failed'} What it means
The notifications pipeline fetches https://gw-c.nowcoder.com/api/sparta/message/pc/unread/detail in-page and throws new Error(d.msg || 'API failed') when the response JSON has success falsy. The resulting CommandExecutionError carries the server-provided msg (or the generic 'API failed'). It means nowcoder's gateway accepted the request but rejected it — usually due to missing/invalid session credentials or an API-level error.
Source
Thrown at clis/nowcoder/notifications.js:16
import { cli } from '@jackwener/opencli/registry';
cli({
site: 'nowcoder',
name: 'notifications',
access: 'read',
description: 'Unread message summary',
domain: 'www.nowcoder.com',
args: [],
columns: ['type', 'unread'],
pipeline: [
{ navigate: 'https://www.nowcoder.com' },
{ evaluate: `(async () => {
const r = await fetch('https://gw-c.nowcoder.com/api/sparta/message/pc/unread/detail', {credentials: 'include'});
const d = await r.json();
if (!d.success) throw new Error(d.msg || 'API failed');
const data = d.data;
return [
{type: 'system', unread: data.systemNotice?.unreadCount || 0},
{type: 'likes', unread: data.likeCollect?.unreadCount || 0},
{type: 'comments', unread: data.commentMessage?.unreadCount || 0},
{type: 'follows', unread: data.followMessage?.unreadCount || 0},
{type: 'messages', unread: data.privateMessage?.unreadCount || 0},
{type: 'job_apply', unread: data.nowPickJobApply?.unreadCount || 0},
{type: 'total', unread: data.total?.unreadCount || 0},
];
})()
` },
],
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Re-authenticate with `nowcoder login` so the request includes a valid session
- Read d.msg in the error for the server's specific reason
- Retry later if msg indicates rate limiting or server trouble
- If success:false with no msg persists, verify the endpoint URL is still valid
Example fix
// before
const unread = await runNowcoderNotifications();
// after
try {
const unread = await runNowcoderNotifications();
} catch (e) {
if (/API failed|nowcoder/.test(e.message)) {
await runNowcoderLogin();
return runNowcoderNotifications();
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
const cookies = await page.getCookies({ url: 'https://www.nowcoder.com' });
if (!cookies.some(c => c.name === 't' && c.value)) {
throw new Error('Login to nowcoder before fetching notifications');
} Type guard
function isApiSuccess(d) {
return !!d && d.success === true && typeof d.data === 'object' && d.data !== null;
} Try / catch
try {
return await nowcoderNotifications();
} catch (e) {
if (/API failed|nowcoder/i.test(e.message)) {
await nowcoderLogin();
return nowcoderNotifications();
}
throw e;
} Prevention
- Always authenticate before querying unread-message APIs
- Surface d.msg from responses rather than swallowing it
- Rate-limit repeated notification polls
- Handle success:false explicitly in your own in-page fetch pipelines
When it happens
Trigger: Calling the nowcoder notifications command while logged out (API returns success:false with auth msg); rate limiting or server-side validation errors returning success:false; API contract change making data absent.
Common situations: Expired `t` cookie so gateway denies the unread-detail call; calling from an IP nowcoder distrusts; nowcoder API returning an error message after a backend change.
Related errors
- ${d.msg || 'API failed'}
- 获取视频分P信息失败: ${payload?.message ?? 'unknown'} (${payload?.cod
- 获取关注列表失败: ${payload.message} (${payload.code})
- 申请抖音上传地址失败: HTTP ${res.status} ${JSON.stringify(error ?? pay
- Douyin user info response is missing user_info
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/1a04ce4d252e29d5.
Report an issue: GitHub.