{"record":{"id":"5a6e63c92f9a2a10","repo":"jackwener/OpenCLI","slug":"no-semantic-scholar-citations-for-args-id-at","errorCode":null,"errorMessage":"No Semantic Scholar citations for \"${args.id}\" at offset ${offset}.","messagePattern":"No Semantic Scholar citations for \"(.+?)\" at offset (.+?)\\.","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"info","filePath":"clis/semanticscholar/citations.js","lineNumber":51,"sourceCode":"        const ref = requirePaperRef(args.id);\n        const limit = requireBoundedInt(args.limit, 20, 1000);\n        const offsetRaw = args.offset ?? 0;\n        const offset = typeof offsetRaw === 'number' ? offsetRaw : Number(offsetRaw);\n        if (!Number.isInteger(offset) || offset < 0) {\n            throw new ArgumentError('semanticscholar citations offset must be a non-negative integer');\n        }\n        if (offset > 9999) {\n            throw new ArgumentError('semanticscholar citations offset must be <= 9999');\n        }\n        const url = `${S2_GRAPH_BASE}/paper/${encodeURIComponent(ref)}/citations?fields=${FIELDS}&limit=${limit}&offset=${offset}`;\n        const body = await s2Fetch(url, 'semanticscholar citations');\n\n        const data = Array.isArray(body?.data) ? body.data : null;\n        if (data === null) {\n            throw new CommandExecutionError('semanticscholar citations returned an unexpected payload shape');\n        }\n        if (!data.length) {\n            throw new EmptyResultError('semanticscholar citations', `No Semantic Scholar citations for \"${args.id}\" at offset ${offset}.`);\n        }\n\n        return data.slice(0, limit).map((entry, i) => {\n            if (!entry || typeof entry !== 'object' || !('citingPaper' in entry)) {\n                throw new CommandExecutionError('semanticscholar citations row is missing citingPaper');\n            }\n            return normalizePaperRow(entry.citingPaper, 'citations', { rank: offset + i + 1 });\n        });\n    },\n});\n","sourceCodeStart":33,"sourceCodeEnd":62,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/semanticscholar/citations.js#L33-L62","documentation":"This EmptyResultError (clis/semanticscholar/citations.js:51) is thrown when the citations endpoint responded correctly but the `data` array was empty at the requested offset. The library treats an empty page as a distinct, expected outcome rather than a failure of the request itself.","triggerScenarios":"Requesting an offset past the last citation (e.g. offset 500 for a paper with 320 citations); citing a paper that genuinely has zero citations; passing an offset > 0 with a limit that skips past all results.","commonSituations":"Auto-pagination loops that page one past the end; querying very new or obscure papers with no citing papers yet; computing offset from stale counts after citations changed; users assuming a paper has citations it does not have.","solutions":["Retry with --offset 0 to confirm the paper has any citations at all.","In pagination loops, catch EmptyResultError and treat it as the normal end-of-results signal.","Check the paper's citationCount (via `semanticscholar paper <id>`) and stop paging at or before it.","Verify the paper id resolves to the intended paper."],"exampleFix":"// before\nlet offset = 0;\nwhile (true) { rows = await citations(id, offset); offset += limit; }\n// after\nlet offset = 0;\ntry {\n  while (true) { rows = await citations(id, offset); offset += limit; }\n} catch (err) {\n  if (!isEmptyResult(err)) throw err; // end of pagination, not a failure\n}","handlingStrategy":"fallback","validationCode":"// Check citationCount before deep paging:\nconst paper = await cli('semanticscholar paper', id, { json: true });\nif (offset >= paper.citationCount) return []; // would be empty — skip the call","typeGuard":"function isEmptyResultError(err) {\n  return err instanceof Error && err.name === 'EmptyResultError';\n}","tryCatchPattern":"try {\n  rows = await citations(id, offset);\n} catch (err) {\n  if (isEmptyResultError(err)) {\n    return { rows: [], done: true }; // normal end of pagination\n  }\n  throw err;\n}","preventionTips":["Treat EmptyResultError as end-of-results in pagination loops, not as failure.","Use the paper's citationCount to bound offset before paging.","Retry with offset 0 first to distinguish 'no citations at all' from 'bad offset'.","Never loop unconditionally without an empty-page termination condition."],"tags":["empty-result","pagination","semanticscholar","expected-condition"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}