jackwener/OpenCLI · error · Error
${d.msg || 'API failed'}
Error message
${d.msg || 'API failed'} What it means
The papers pipeline POSTs to nowcoder's gateway and throws new Error(d.msg || 'API failed') when the response JSON has success falsy. Since the papers list API is wrapped in the library's error handling, the resulting CommandExecutionError surfaces the server's msg or the fallback 'API failed'. This mirrors 2858 but for the company papers/practice-ranking endpoint.
Source
Thrown at clis/nowcoder/papers.js:30
{ name: 'limit', type: 'int', default: 10, help: 'Number of items' },
],
columns: ['rank', 'title', 'company', 'practitioners'],
pipeline: [
{ navigate: 'https://www.nowcoder.com' },
{ evaluate: `(async () => {
const jobId = parseInt(\${{ args.job | json }});
const companyId = \${{ args.company | json }};
const limit = \${{ args.limit }};
const body = {jobId, page: 1, pageSize: limit};
if (companyId) body.companyId = parseInt(companyId);
const r = await fetch('https://gw-c.nowcoder.com/api/sparta/company-question/get-paper-list', {
method: 'POST',
credentials: 'include',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(body)
});
const d = await r.json();
if (!d.success) throw new Error(d.msg || 'API failed');
return (d.data?.records || []).map((p, i) => ({
rank: i + 1,
title: p.paperName || '',
company: p.companyTag?.name || '',
practitioners: p.practiceCnt || 0,
}));
})()
` },
{ limit: '${{ args.limit }}' },
],
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Log in first (`nowcoder login`) so credentials are included — many paper endpoints require auth
- Inspect the server's msg in the error for the exact rejection reason
- Retry with backoff if the message indicates rate limiting or server issues
- Check that the POST body schema still matches the current API; update the pipeline if nowcoder changed it
Example fix
// before
const papers = await runNowcoderPapers({ company: 'bytedance' });
// after
try {
const papers = await runNowcoderPapers({ company: 'bytedance' });
} catch (e) {
if (/API failed/.test(e.message)) {
await runNowcoderLogin();
await new Promise(r => setTimeout(r, 3000));
return runNowcoderPapers({ company: 'bytedance' });
}
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 papers');
} Type guard
function isApiSuccess(d) {
return !!d && d.success === true && Array.isArray(d.data?.records);
} Try / catch
try {
return await nowcoderPapers(query);
} catch (e) {
if (/API failed/.test(e.message)) {
await sleep(5000);
return nowcoderPapers(query); // single retry with backoff
}
throw e;
} Prevention
- Log in before hitting papers endpoints that require a session
- Add exponential backoff around nowcoder gateway calls
- Validate the POST body schema after any nowcoder API update
- Log d.msg responses to diagnose success:false rejections quickly
When it happens
Trigger: Calling the nowcoder papers command with a request body the API rejects; unauthenticated/guest session being denied; nowcoder backend returning success:false due to rate limit, maintenance, or changed request schema.
Common situations: Anonymous access to a members-only ranking; request payload fields renamed after a nowcoder API update; transient gateway errors during high traffic (e.g. around recruitment seasons).
Related errors
- ${d.msg || 'API failed'}
- Bilibili creator comparison API failed: ${message} (${payloa
- [风控拦截/未登录] 获取到的 subtitle_url 为空!请确保 CLI 已成功登录且风控未封锁此账号。
- Bilibili view API failed: ${payload.message} (${payload.code
- Douyin user info response is missing user_info
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/baa938e9180b5c7b.
Report an issue: GitHub.