jackwener/OpenCLI · error · ArgumentError
semanticscholar citations offset must be <= 9999
Error message
semanticscholar citations offset must be <= 9999
What it means
The semanticscholar citations command caps the pagination offset at 9999 (clis/semanticscholar/citations.js:41) because the Semantic Scholar Graph API itself will not serve pages beyond that depth. Values above 9999 are rejected locally with an ArgumentError before any request is made.
Source
Thrown at clis/semanticscholar/citations.js:41
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' },
{ name: 'limit', type: 'int', default: 20, help: 'Max citing papers (1-1000, single Semantic Scholar page)' },
{ name: 'offset', type: 'int', default: 0, help: 'Page offset (0-based)' },
],
columns: ['rank', 'paperId', 'doi', 'title', 'year', 'firstAuthor', 'citationCount', 'url'],
func: async (args) => {
const ref = requirePaperRef(args.id);
const limit = requireBoundedInt(args.limit, 20, 1000);
const offsetRaw = args.offset ?? 0;
const offset = typeof offsetRaw === 'number' ? offsetRaw : Number(offsetRaw);
if (!Number.isInteger(offset) || offset < 0) {
throw new ArgumentError('semanticscholar citations offset must be a non-negative integer');
}
if (offset > 9999) {
throw new ArgumentError('semanticscholar citations offset must be <= 9999');
}
const url = `${S2_GRAPH_BASE}/paper/${encodeURIComponent(ref)}/citations?fields=${FIELDS}&limit=${limit}&offset=${offset}`;
const body = await s2Fetch(url, 'semanticscholar citations');
const data = Array.isArray(body?.data) ? body.data : null;
if (data === null) {
throw new CommandExecutionError('semanticscholar citations returned an unexpected payload shape');
}
if (!data.length) {
throw new EmptyResultError('semanticscholar citations', `No Semantic Scholar citations for "${args.id}" at offset ${offset}.`);
}
return data.slice(0, limit).map((entry, i) => {
if (!entry || typeof entry !== 'object' || !('citingPaper' in entry)) {
throw new CommandExecutionError('semanticscholar citations row is missing citingPaper');
}
return normalizePaperRow(entry.citingPaper, 'citations', { rank: offset + i + 1 });
});View on GitHub (pinned to 49907e53dc)
Solutions
- Clamp offset to <= 9999 in your pagination loop and stop paging there.
- Narrow the result set instead of deep-paging (e.g. filter by year using other endpoints) to reach items below the cap.
- Break the loop when offset + limit would exceed 9999.
- For very large citation lists, fetch via the Semantic Scholar API/datasets directly rather than unbounded paging.
Example fix
// before
while (true) { await fetchPage(offset); offset += limit; }
// after
while (offset <= 9999) {
await fetchPage(offset);
offset += limit;
if (offset > 9999) break; // API caps pagination at 9999
} Defensive patterns
Strategy: validation
Validate before calling
const S2_OFFSET_CAP = 9999;
function clampOffset(raw) {
const n = typeof raw === 'number' ? raw : Number(raw);
return Math.min(Math.max(0, Number.isInteger(n) ? n : 0), S2_OFFSET_CAP);
}
// use before calling: clampOffset(args.offset) Type guard
function isWithinOffsetCap(v) {
const n = typeof v === 'number' ? v : Number(v);
return Number.isInteger(n) && n >= 0 && n <= 9999;
} Try / catch
try {
await cli('semanticscholar citations', id, { offset });
} catch (err) {
if (/offset must be <= 9999/.test(err.message)) {
console.error('S2 caps pagination at offset 9999; stopping deep paging.');
return; // end collection here
}
throw err;
} Prevention
- Stop pagination loops when offset + limit > 9999 instead of waiting for an error.
- Clamp offsets programmatically before every call.
- For very large citation lists, use the S4 datasets/API export rather than deep paging.
- Never compute offset from unbounded counters.
When it happens
Trigger: Calling `semanticscholar citations <id> --offset 10000` or higher, typically from a naive auto-pagination loop that keeps incrementing offset until an EmptyResultError instead of stopping at the cap.
Common situations: Bulk-harvesting citation lists of heavily-cited papers (tens of thousands of citations) with a `while` loop; computing offset as result-count without clamping; migrating code from another API without page limits.
Related errors
- ${label} must be <= ${maxValue}
- semanticscholar citations offset must be a non-negative inte
- ${label} must be a positive integer
- arxiv ${label} must be <= ${maxValue}
- Bilibili view API did not return pages[] for --page selectio
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/60815f5fc096c253.
Report an issue: GitHub.