jackwener/OpenCLI · error · CommandExecutionError

TikTok Studio item_list failed: ${detail}

Error message

TikTok Studio item_list failed: ${detail}

What it means

item_list returned a non-2xx status (other than 401/403), or the response body was not valid JSON. The library builds a detail string ('invalid JSON (...)' or 'HTTP <status> <statusText>') and throws a CommandExecutionError, optionally attaching a response preview as a second argument.

Source

Thrown at clis/tiktok/creator-videos.js:203

async function fetchCreatorVideosPage(page, cursor, size) {
    const result = await page.evaluate(buildFetchItemListScript(buildItemListRequest(cursor, size))).catch((error) => {
        throw new CommandExecutionError(`Failed to fetch TikTok Studio item_list: ${getErrorMessage(error)}`);
    });
    if (!result || typeof result !== 'object') {
        throw new CommandExecutionError('TikTok Studio item_list returned an unreadable response');
    }
    if (result.networkError) {
        throw new CommandExecutionError(`TikTok Studio item_list network failure: ${result.networkError}`);
    }
    if (result.status === 401 || result.status === 403) {
        throw new AuthRequiredError('www.tiktok.com', `TikTok Studio item_list requires login (HTTP ${result.status})`);
    }
    if (!result.ok) {
        const detail = result.parseError
            ? `invalid JSON (${result.parseError})`
            : `HTTP ${result.status || 0}${result.statusText ? ` ${result.statusText}` : ''}`;
        throw new CommandExecutionError(`TikTok Studio item_list failed: ${detail}`, result.text ? `Response preview: ${result.text}` : undefined);
    }
    const payload = unwrapPayload(result.data);
    assertApiSuccess(payload);
    return payload;
}

async function listCreatorVideos(page, args) {
    const limit = requirePositiveInt(args.limit, 'limit', DEFAULT_LIMIT, MAX_LIMIT);
    let nextCursor = requireCursor(args.cursor);
    const rows = [];
    let skippedMissingId = 0;
    const pageSize = limit > SERVER_PAGE_MAX ? SERVER_PAGE_MAX : limit;
    const maxPages = Math.ceil(limit / pageSize);

    await page.goto(STUDIO_CONTENT_URL, { waitUntil: 'load', settleMs: 6000 });

    for (let pageIndex = 0; pageIndex < maxPages && rows.length < limit; pageIndex += 1) {
        const data = await fetchCreatorVideosPage(page, nextCursor, pageSize);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Inspect the attached response preview (result.text) to see what TikTok actually returned
  2. On HTTP 429, back off significantly (minutes, not seconds) and reduce request rate/page.wait values
  3. If the preview shows HTML/captcha, solve the challenge in the browser profile before retrying
  4. Retry on 5xx after a short delay — often transient TikTok server issues
  5. Check the response statusText to distinguish rate limit vs server error

Example fix

// before
const rows = await listCreatorVideos(page, { limit: 100 });
// after
try {
  const rows = await listCreatorVideos(page, { limit: 100 });
} catch (e) {
  if (/HTTP 429/.test(e.message)) { await sleep(60000); /* retry with lower rate */ }
  else throw e;
}
Defensive patterns

Strategy: retry

Type guard

function isHttpFailure(r) { return !!r && typeof r === 'object' && r.ok === false && ![401,403].includes(r.status); }

Try / catch

try {
  rows = await listCreatorVideos(page, opts);
} catch (e) {
  if (/HTTP 429/.test(e.message)) { await sleep(60000); /* reduce rate */ }
  else if (/invalid JSON|HTTP 5\d\d/.test(e.message)) { await sleep(5000); /* retry */ }
  else throw e;
}

Prevention

When it happens

Trigger: result.ok false: any 4xx/5xx besides 401/403 (429 rate limit, 5xx server error), or result.parseError set because the body wasn't JSON (HTML error page, login wall HTML, empty body).

Common situations: TikTok rate limiting (429) after heavy scraping, TikTok serving an HTML challenge/captcha page instead of JSON, regional blocks returning error pages, or TikTok API outages (5xx).

Related errors


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