jackwener/OpenCLI · error
API failed
Error message
API failed
What it means
The nowcoder salary command's in-page script fetches gw-c.nowcoder.com/api/sparta/home/tab/content (tabId=858, salary tab). When the response has success:false it throws Error(d.msg || 'API failed'); 'API failed' appears when the server supplies no message. It means the salary tab API rejected the request.
Source
Thrown at clis/nowcoder/salary.js:21
cli({
site: 'nowcoder',
name: 'salary',
access: 'read',
description: 'Salary disclosure posts',
domain: 'www.nowcoder.com',
args: [
{ name: 'page', type: 'int', default: 1, help: 'Page number' },
{ name: 'limit', type: 'int', default: 15, help: 'Number of items' },
],
columns: ['rank', 'title', 'author', 'school', 'likes', 'comments', 'views', 'id'],
pipeline: [
{ navigate: 'https://www.nowcoder.com' },
{ evaluate: `(async () => {
const page = \${{ args.page }};
const limit = \${{ args.limit }};
const r = await fetch('https://gw-c.nowcoder.com/api/sparta/home/tab/content?tabId=858&categoryType=1&pageNo=' + page + '&pageSize=' + limit, {credentials: 'include'});
const d = await r.json();
if (!d.success) throw new Error(d.msg || 'API failed');
return (d.data?.records || []).map((item, i) => {
const moment = item.momentData || {};
const content = item.contentData || {};
return {
rank: i + 1,
title: moment.title || content.title || '',
author: item.userBrief?.nickname || '',
school: item.userBrief?.educationInfo || '',
likes: item.frequencyData?.likeCnt || 0,
comments: item.frequencyData?.commentCnt || 0,
views: item.frequencyData?.viewCnt || 0,
id: moment.uuid || content.uuid || item.contentId || '',
};
});
})()
` },
{ filter: 'item.title' },
{ limit: '${{ args.limit }}' },View on GitHub (pinned to 49907e53dc)
Solutions
- Log in to nowcoder.com in the automated browser so the fetch carries session credentials
- Start from page 1 with a modest limit and confirm the tab still returns data in a real browser
- Retry after a delay if the gateway is throttling
- Verify tabId 858 is still valid and update clis/nowcoder/salary.js if the API changed
Example fix
// before
if (!d.success) throw new Error(d.msg || 'API failed');
// after
if (!r.ok) throw new Error('HTTP ' + r.status);
const d = await r.json();
if (!d.success) throw new Error(d.msg || 'salary API failed (code=' + d.code + ')'); Defensive patterns
Strategy: retry
Validate before calling
const pageNo = Math.max(1, Number(page) || 1); const pageSize = Math.min(50, Math.max(1, Number(limit) || 10));
Type guard
function tabContentOk(d){ return !!d && typeof d === 'object' && d.success === true && Array.isArray(d.data?.records); } Try / catch
try { await run(['nowcoder', 'salary']); }
catch (e) {
if (String(e.message).includes('API failed')) { await sleep(3000); /* retry once, or re-login */ }
else throw e;
} Prevention
- Log in to nowcoder.com in the driving browser before running salary queries
- Confirm tabId 858 (salary tab) is still valid after Nowcoder changes
- Avoid deep pagination past available pages
- Check r.ok before parsing JSON to separate network from business failures
When it happens
Trigger: Running `nowcoder salary` when the tab/content endpoint returns success:false with no msg — bad page/limit values, absent Nowcoder session cookie, endpoint change, or rate limiting.
Common situations: Unauthenticated browser session; Nowcoder retiring or renumbering tabId 858; deep pagination past the last page; transient gateway (gw-c) incidents.
Related errors
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/4d52947de099ff9a.
Report an issue: GitHub.