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

  1. Log in first (`nowcoder login`) so credentials are included — many paper endpoints require auth
  2. Inspect the server's msg in the error for the exact rejection reason
  3. Retry with backoff if the message indicates rate limiting or server issues
  4. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/baa938e9180b5c7b. Report an issue: GitHub.