jackwener/OpenCLI · warning · Error

RATE_LIMITED

RATE_LIMITED

Error message

RATE_LIMITED: TikTok rate limit / captcha detected

What it means

ensureNoRateLimitOrThrow detects a rate-limit/captcha popup on the TikTok page and throws 'RATE_LIMITED: TikTok rate limit / captcha detected'. This typed marker lets the CLI distinguish throttling from auth or execution failures and stop hammering the endpoint.

Source

Thrown at clis/tiktok/utils.js:502

  const timeoutMs = typeof opts.timeoutMs === 'number' ? opts.timeoutMs : 5000;
  const intervalMs = typeof opts.intervalMs === 'number' ? opts.intervalMs : 200;
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    try { if (predicate()) return true; } catch { /* swallow predicate errors */ }
    await new Promise((r) => setTimeout(r, intervalMs));
  }
  return false;
}

function ensureLoggedInOrThrow() {
  if (!checkLoggedIn()) {
    throw new Error('AUTH_REQUIRED: TikTok login required');
  }
}

function ensureNoRateLimitOrThrow() {
  if (detectRateLimitPopup()) {
    throw new Error('RATE_LIMITED: TikTok rate limit / captcha detected');
  }
}
`;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pause and wait (minutes to hours) before retrying; the popup often clears
  2. Add delays/jitter between page loads and API calls
  3. Switch to a residential proxy or different IP
  4. Reduce concurrency: serialize requests from a single TikTok session

Example fix

// before
for (const id of ids) await scrapeOne(id); // tight loop triggers RATE_LIMITED
// after
for (const id of ids) {
  await scrapeOne(id);
  await sleep(2000 + Math.random() * 2000); // backoff between requests
}
Defensive patterns

Strategy: retry

Validate before calling

const limited = await page.evaluate(() =>
  !!document.querySelector('[class*="captcha"], [class*="verify"], iframe[src*="captcha"]'));
if (limited) throw new Error('RATE_LIMITED: back off before continuing');

Type guard

function isRateLimited(e) { return /RATE_LIMITED/i.test(e?.message || ''); }

Try / catch

try { await scrape(); } catch (e) {
  if (isRateLimited(e)) {
    await sleep(COOLDOWN_MS); // minutes, not seconds
    return scrape();
  }
  throw e;
}

Prevention

When it happens

Trigger: detectRateLimitPopup() found a captcha or rate-limit overlay on the current TikTok page — usually after too many rapid navigations or API hits from one session/IP.

Common situations: Tight scraping loops without delays; shared datacenter IP already flagged by TikTok; many parallel browser sessions from one account.

Related errors


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