jackwener/OpenCLI · error · ArgumentError
cursor must be a safe integer
Error message
cursor must be a safe integer
What it means
After the regex check passes, requireCursor converts the cursor to a JavaScript number and verifies it is a safe integer (within Number.MAX_SAFE_INTEGER). Extremely large digit strings that lose precision as doubles throw this ArgumentError, preventing silently wrong pagination offsets.
Source
Thrown at clis/tiktok/creator-videos.js:36
const parsed = Number(raw);
if (!Number.isInteger(parsed) || parsed <= 0) {
throw new ArgumentError(`${label} must be a positive integer`, `Example: opencli tiktok creator-videos --${label} ${defaultValue}`);
}
if (parsed > maxValue) {
throw new ArgumentError(`${label} must be <= ${maxValue}`, `Example: opencli tiktok creator-videos --${label} ${maxValue}`);
}
return parsed;
}
function requireCursor(value) {
const raw = value ?? '0';
const text = String(raw).trim();
if (!/^\d+$/.test(text)) {
throw new ArgumentError('cursor must be a non-negative integer string', 'Example: opencli tiktok creator-videos --cursor 0');
}
const cursor = Number(text);
if (!Number.isSafeInteger(cursor)) {
throw new ArgumentError('cursor must be a safe integer', 'Example: opencli tiktok creator-videos --cursor 0');
}
return cursor;
}
function buildItemListRequest(cursor, size) {
return {
cursor,
size,
query: {
conditions: [],
sort_orders: [{ field_name: 'create_time', order: 2 }],
},
};
}
function buildFetchItemListScript(body) {
const request = {
url: `${ITEM_LIST_API_PATH}?aid=1988`,View on GitHub (pinned to 49907e53dc)
Solutions
- Use a smaller, previously-returned nextCursor value.
- Restart pagination from --cursor 0.
- If the server genuinely returns huge cursors, update the library to keep the cursor as a string instead of coercing to Number.
Example fix
// before
const cursor = Number(text);
// after
const cursor = Number(text);
if (!Number.isSafeInteger(cursor)) {
throw new ArgumentError('cursor must be a safe integer', 'Example: opencli tiktok creator-videos --cursor 0');
} Defensive patterns
Strategy: validation
Validate before calling
const cursor = String(process.env.TT_CURSOR ?? '0').trim();
if (!/^\d+$/.test(cursor) || !Number.isSafeInteger(Number(cursor))) {
throw new Error(`cursor '${cursor}' is not a safe non-negative integer`);
} Type guard
const isSafeCursor = (v) => /^\d+$/.test(String(v).trim()) && Number.isSafeInteger(Number(String(v).trim()));
Try / catch
try {
await run(['tiktok', 'creator-videos', '--cursor', rawCursor]);
} catch (e) {
if (String(e.message).includes('cursor must be a safe integer')) {
console.error(`Cursor ${rawCursor} exceeds safe integer range; restarting from 0`);
await run(['tiktok', 'creator-videos', '--cursor', '0']);
} else throw e;
} Prevention
- Keep cursors within Number.MAX_SAFE_INTEGER; treat them as opaque strings from the previous response.
- Reject oversized cursors in your own scripts before invoking the CLI.
- Restart pagination from 0 if a stored cursor fails the safe-integer check.
When it happens
Trigger: Passing a cursor like --cursor 99999999999999999999 (more than ~15-16 digits) — matches /^\d+$/ but Number(text) is not a safe integer.
Common situations: Pasting oversized/obfuscated numbers by mistake; a bug in the caller generating cursors; a TikTok response change producing cursor values the CLI can no longer represent.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- ${label} must be <= ${maxValue}
- cursor must be a non-negative integer string
- boss ${name} must be a positive integer
- coingecko limit must be <= 250 (per_page upper bound)
- coingecko page must be a positive integer
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a78aab58e7df0298.
Report an issue: GitHub.