jackwener/OpenCLI · error · Error

API failed:

Error message

 API failed: 

What it means

The non-auth branch of assertTikTokApiSuccess: a TikTok API payload with a non-zero status_code whose message does not look auth-related is thrown as `<label> API failed: <message>`. The literal ' API failed: ' is the seam between the caller-supplied label and TikTok's status_msg.

Source

Thrown at clis/tiktok/utils.js:256

    throw new Error('HTTP ' + res.status + ' from ' + requestUrl + ': ' + text.slice(0, 160));
  }
  if (!text.trim()) return {};
  try {
    return JSON.parse(text);
  } catch (error) {
    throw new Error('invalid JSON from ' + requestUrl + ': ' + (error instanceof Error ? error.message : String(error)));
  }
}

function assertTikTokApiSuccess(data, label) {
  if (!data || typeof data !== 'object') return;
  const code = data.status_code ?? data.statusCode;
  if (code === undefined || code === null || Number(code) === 0) return;
  const message = cleanText(data.status_msg ?? data.statusMsg ?? data.message ?? data.msg ?? code, 240);
  if (Number(code) === 8 || /auth|captcha|login|permission|unauthori[sz]ed|forbidden/i.test(message)) {
    throw new Error('AUTH_REQUIRED: ' + label + ' API failed: ' + message);
  }
  throw new Error(label + ' API failed: ' + message);
}

function findUniversalData() {
  const scripts = Array.from(document.querySelectorAll('script'));
  for (const script of scripts) {
    const text = script.textContent || '';
    if (!text || text.length < 32) continue;
    const trimmed = text.trim();
    if (!(trimmed.startsWith('{') || trimmed.startsWith('['))) continue;
    if (
      !text.includes('webapp.user-detail') &&
      !text.includes('webapp.recommend-feed') &&
      !text.includes('webapp.live-discover') &&
      !text.includes('ItemModule') &&
      !text.includes('itemList') &&
      !text.includes('userInfo') &&
      !text.includes('userList') &&
      !text.includes('noticeList')

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read status_msg after 'API failed: ' — it is TikTok's own error description
  2. Verify the input parameters (user id / video id) still exist and are public
  3. Map the numeric status_code via TikTok API docs to the specific failure
  4. If the message is actually auth-flavored, report/extend the regex so it routes to AUTH_REQUIRED

Example fix

// before
assertTikTokApiSuccess(data, 'user/detail');
// after
try {
  assertTikTokApiSuccess(data, 'user/detail');
} catch (e) {
  if (e.message.includes('user/detail API failed')) {
    console.warn('TikTok rejected request:', e.message);
  }
  throw e;
}
Defensive patterns

Strategy: validation

Validate before calling

const code = data?.status_code ?? data?.statusCode;
if (code !== undefined && Number(code) !== 0) console.warn(label, 'reports status', code, data?.status_msg ?? data?.statusMsg);

Type guard

function isApiSuccess(data) {
  if (!data || typeof data !== 'object') return true;
  const code = data.status_code ?? data.statusCode;
  return code === undefined || code === null || Number(code) === 0;
}

Try / catch

if (!isApiSuccess(data)) {
  console.warn(`${label} failed:`, data.status_msg ?? data.statusMsg);
  return null; // skip and continue instead of aborting the batch
}

Prevention

When it happens

Trigger: TikTok API returned status_code other than 0/8 with a status_msg not matching the auth regex — e.g. content removed, parameter errors, or private/region-locked data.

Common situations: Querying a deleted or private account; wrong parameter format for the endpoint; TikTok API returning a business error code (content not exist, forbidden region) that isn't auth-related.

Related errors


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