{"record":{"id":"826c5d99c0939cd9","repo":"jackwener/OpenCLI","slug":"api-failed","errorCode":null,"errorMessage":"API failed","messagePattern":"API failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"clis/nowcoder/practice.js","lineNumber":21,"sourceCode":"cli({\n    site: 'nowcoder',\n    name: 'practice',\n    access: 'read',\n    description: 'Categorized practice questions with progress',\n    domain: 'www.nowcoder.com',\n    args: [\n        { name: 'job', type: 'str', default: '11226', help: 'Career ID (11226=Software, 11227=Hardware, 11229=Product, 11230=Finance)' },\n        { name: 'limit', type: 'int', default: 20, help: 'Number of items' },\n    ],\n    columns: ['category', 'subject', 'total', 'done', 'remaining'],\n    pipeline: [\n        { navigate: 'https://www.nowcoder.com' },\n        { evaluate: `(async () => {\n  const jobId = \\${{ args.job | json }};\n  const limit = \\${{ args.limit }};\n  const r = await fetch('https://gw-c.nowcoder.com/api/sparta/intelligent/getPCIntelligentList?jobId=' + jobId, {credentials: 'include'});\n  const d = await r.json();\n  if (!d.success) throw new Error(d.msg || 'API failed');\n  const all = [];\n  for (const tag of (d.data?.tags || [])) {\n    for (const item of (tag.items || [])) {\n      all.push({\n        category: tag.title || 'recommended',\n        subject: item.title,\n        total: item.tcount,\n        done: item.rcount,\n        remaining: item.leftCount,\n      });\n    }\n  }\n  return all.slice(0, limit);\n})()\n` },\n    ],\n});\n","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/nowcoder/practice.js#L3-L39","documentation":"Inside the browser-evaluated script of the nowcoder practice command, the getPCIntelligentList response is checked with if (!d.success) throw new Error(d.msg || 'API failed'). So 'API failed' is the in-page fallback message shown when Nowcoder's intelligent-recommendation API returns success:false and supplies no msg. The error is thrown inside the page context and then surfaces as the command's failure.","triggerScenarios":"Running `nowcoder practice` when gw-c.nowcoder.com/api/sparta/intelligent/getPCIntelligentList responds with success:false (bad jobId, not logged in with credentials:'include', throttled, or API decommissioned), and d.msg is empty.","commonSituations":"An invalid or stale jobId argument; an expired Nowcoder session so the personalized recommendation endpoint refuses; Nowcoder renaming/retiring the sparta intelligent API.","solutions":["Re-run with a valid jobId (check the job list on nowcoder.com)","Log in to nowcoder.com in the automated browser so the include-credentials fetch carries a session","Retry later — the endpoint may be rate limiting","Inspect the current API response and update the endpoint/params in clis/nowcoder/practice.js if the schema changed"],"exampleFix":"// before\nconst r = await fetch('...getPCIntelligentList?jobId=' + jobId, {credentials:'include'});\n// after\nconst r = await fetch('...getPCIntelligentList?jobId=' + jobId, {credentials:'include'});\nif (!r.ok) throw new Error('HTTP ' + r.status); // distinguish transport vs business errors\nconst d = await r.json();","handlingStrategy":"retry","validationCode":"// validate args before running the command\nif (!Number.isSafeInteger(jobId) || jobId <= 0) throw new Error('valid jobId required');","typeGuard":"function hasSuccess(d){ return !!d && typeof d === 'object' && d.success === true; }","tryCatchPattern":"try { await run(['nowcoder', 'practice', '--job', String(jobId)]); }\ncatch (e) {\n  if (String(e.message).includes('API failed')) { await sleep(3000); retryOnce(); } // often transient/session\n  else throw e;\n}","preventionTips":["Ensure the browser session is logged in to nowcoder.com (credentials:'include' fetch)","Verify the jobId is current; job ids can become stale","Add HTTP status checks before r.json() to separate transport from business errors","Back off on repeated failures — the intelligent endpoint rate limits"],"tags":["nowcoder","in-page-script","api-error"],"backgroundTag":"api-business-error-code","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}