jackwener/OpenCLI · error · CommandExecutionError
semanticscholar paper returned an unexpected payload shape
Error message
semanticscholar paper returned an unexpected payload shape
What it means
The semanticscholar paper command (clis/semanticscholar/paper.js:41) expects `/paper/{ref}` to return a JSON object with the paper's fields. If the parsed body is null, an array, or otherwise not an object, this CommandExecutionError is thrown because the single-paper payload contract was violated.
Source
Thrown at clis/semanticscholar/paper.js:41
cli({
site: 'semanticscholar',
name: 'paper',
access: 'read',
description: 'Semantic Scholar paper detail (citation graph + AI tldr) by paperId, DOI, or arXiv id',
domain: 'api.semanticscholar.org',
strategy: Strategy.PUBLIC,
browser: false,
args: [
{ name: 'id', positional: true, required: true, help: 'paperId (40-char hex), DOI, arXiv id, or prefixed id (e.g. "ARXIV:1706.03762", "PMID:12345")' },
],
columns: ['paperId', 'doi', 'title', 'year', 'firstAuthor', 'citationCount', 'influentialCitationCount', 'referenceCount', 'tldr', 'url'],
func: async (args) => {
const ref = requirePaperRef(args.id);
const url = `${S2_GRAPH_BASE}/paper/${encodeURIComponent(ref)}?fields=${FIELDS}`;
const body = await s2Fetch(url, 'semanticscholar paper');
if (!body || typeof body !== 'object') {
throw new CommandExecutionError('semanticscholar paper returned an unexpected payload shape');
}
const row = normalizePaperRow(body, 'paper');
return [{
...row,
influentialCitationCount: optionalNumber(body.influentialCitationCount, 'paper influentialCitationCount'),
referenceCount: optionalNumber(body.referenceCount, 'paper referenceCount'),
tldr: tldrText(body.tldr),
}];
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect the raw body (curl the URL) to see what came back instead of a paper object.
- Retry after a pause — S2 soft errors with 200 are usually throttling-related and transient.
- Verify the paper reference is valid with a fresh lookup (try paperId, DOI, or arXiv forms).
- Check the Semantic Scholar API changelog for response format changes and update the client.
- Bypass any proxy to rule out an intermediary substituting the body.
Example fix
// before
const body = await s2Fetch(url, 'semanticscholar paper');
const row = normalizePaperRow(body, 'paper');
// after
const body = await s2Fetch(url, 'semanticscholar paper');
if (!body || typeof body !== 'object' || Array.isArray(body) || body.error) {
throw new Error(`S2 paper lookup failed: ${JSON.stringify(body).slice(0, 200)}`);
}
const row = normalizePaperRow(body, 'paper'); Defensive patterns
Strategy: type-guard
Validate before calling
function isPaperObject(body) {
return body !== null && typeof body === 'object' && !Array.isArray(body) && typeof body.paperId === 'string';
} Type guard
function isPaperRow(body) {
return typeof body === 'object' && body !== null && !Array.isArray(body)
&& 'paperId' in body && 'title' in body;
} Try / catch
try {
paper = await cli('semanticscholar paper', id);
} catch (err) {
if (/unexpected payload shape/.test(err.message)) {
await sleep(1500);
paper = await cli('semanticscholar paper', id); // throttling soft errors are transient
} else throw err;
} Prevention
- Retry with backoff — S2 serves soft error bodies with HTTP 200 under load.
- Verify paper refs resolve before batch runs (one cheap probe call).
- Log raw bodies on shape failures to distinguish throttling from schema drift.
- Subscribe to Semantic Scholar API status/changelog updates.
When it happens
Trigger: The API returned 200 with a non-object JSON body — e.g. a JSON array, a bare string/number, null, or a soft-error envelope from Semantic Scholar served with HTTP 200 instead of the paper object.
Common situations: Semantic Scholar throttling or maintenance pages returned as JSON with 200; a proxy returning its own JSON body; an API response-shape change; requests redirected to an endpoint that answers with a different document type.
Related errors
- semanticscholar citations returned an unexpected payload sha
- semanticscholar recommendations returned an unexpected paylo
- workspace/create returned no workspace_id: ${JSON.stringify(
- semanticscholar citations row is missing citingPaper
- Bilibili user search returned malformed result for ${input}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/760880af63e72202.
Report an issue: GitHub.