{"record":{"id":"988fd3877b1b50e4","repo":"jackwener/OpenCLI","slug":"label-returned-an-error-body-error","errorCode":null,"errorMessage":"${label} returned an error: ${body.error}","messagePattern":"(.+?) returned an error: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/semanticscholar/utils.js","lineNumber":131,"sourceCode":"        throw new EmptyResultError(label, `Semantic Scholar returned 404 for ${url}.`);\n    }\n    if (resp.status === 429) {\n        throw new CommandExecutionError(\n            `${label} returned HTTP 429 (rate limited)`,\n            'Semantic Scholar throttles anonymous traffic; set SEMANTIC_SCHOLAR_API_KEY (free at https://www.semanticscholar.org/product/api) or wait a minute and retry.',\n        );\n    }\n    if (!resp.ok) {\n        throw new CommandExecutionError(`${label} returned HTTP ${resp.status}`);\n    }\n    let body;\n    try {\n        body = await resp.json();\n    } catch (err) {\n        throw new CommandExecutionError(`${label} returned malformed JSON: ${err?.message ?? err}`);\n    }\n    if (body && typeof body === 'object' && body.error) {\n        throw new CommandExecutionError(`${label} returned an error: ${body.error}`);\n    }\n    return body;\n}\n\n/** Return the AI-generated one-line summary if present, else ''. */\nexport function tldrText(tldr) {\n    if (tldr && typeof tldr === 'object' && typeof tldr.text === 'string') {\n        return tldr.text.trim();\n    }\n    return '';\n}\n\n/** First author display name, or '' when authors is missing. */\nexport function firstAuthorName(authors) {\n    if (!Array.isArray(authors) || !authors.length) return '';\n    const first = authors[0];\n    if (first && typeof first === 'object' && typeof first.name === 'string') {\n        return first.name.trim();","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/semanticscholar/utils.js#L113-L149","documentation":"When the Semantic Scholar response parses as JSON but contains a truthy `error` field (API-level error object inside a 200 or ok response), s2Fetch surfaces it as CommandExecutionError `${label} returned an error: ${body.error}`. This is the API's own application error, not a transport failure.","triggerScenarios":"The graph/recommendations API returns {\"error\": ...} — e.g. invalid query combination, dataset not found, or recommendations backend unable to produce suggestions for the given paperId.","commonSituations":"Calling recommendations for a paper with no embedding (obscure/new papers), malformed CorpusId, or Semantic Scholar returning structured API errors while still sending a 2xx status.","solutions":["Read body.error from the message for the API's own explanation.","For recommendations errors, try a different or better-known paper ref (DOI or canonical S2 paperId).","Re-check the query string: remove invalid fields or parameters the API flagged.","Retry later if the error indicates a backend problem; otherwise fix the request payload."],"exampleFix":"// before\nconst recs = await s2Fetch(`${S2_REC_BASE}/papers/forpaper/${ref}?fields=title`, 'recommendations');\n// after: fall back when the API reports an in-band error\ntry {\n  const recs = await s2Fetch(`${S2_REC_BASE}/papers/forpaper/${ref}?fields=title`, 'recommendations');\n} catch (e) {\n  if (/returned an error/.test(e.message)) return []; // no recommendations available\n  throw e;\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":"function hasApiError(body) {\n  return body !== null && typeof body === 'object' && 'error' in body && Boolean(body.error);\n}","tryCatchPattern":"try {\n  return await s2Fetch(url, 'recommendations');\n} catch (err) {\n  if (/returned an error/.test(err.message)) {\n    return { recommendations: [] }; // graceful empty fallback\n  }\n  throw err;\n}","preventionTips":["Use canonical refs (DOI, arXiv id, or 40-hex paperId) for best API coverage.","Treat in-band API errors as 'no data' for optional features like recommendations.","Log body.error content to spot recurring request-shape problems."],"tags":["api","semantic-scholar","error-response"],"backgroundTag":"api-error-payload","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}