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

  1. Use a smaller, previously-returned nextCursor value.
  2. Restart pagination from --cursor 0.
  3. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/a78aab58e7df0298. Report an issue: GitHub.