jackwener/OpenCLI · error · CommandExecutionError

TikTok Studio item_list returned videos without stable video

Error message

TikTok Studio item_list returned videos without stable video_id

What it means

After paginating through item_list, every returned row lacked a stable video id, so no usable rows could be produced even though items existed (skippedMissingId > 0). The library throws because silently returning zero rows would hide an API response-shape change.

Source

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

    for (let pageIndex = 0; pageIndex < maxPages && rows.length < limit; pageIndex += 1) {
        const data = await fetchCreatorVideosPage(page, nextCursor, pageSize);
        const items = Array.isArray(data.item_list) ? data.item_list : [];
        for (const item of items) {
            const row = normalizeRow(item);
            if (!row) {
                skippedMissingId += 1;
                continue;
            }
            rows.push(row);
            if (rows.length >= limit) break;
        }
        if (!data.has_more || items.length === 0) break;
        nextCursor = requireCursor(data.cursor);
        await page.wait(250);
    }

    if (rows.length === 0 && skippedMissingId > 0) {
        throw new CommandExecutionError('TikTok Studio item_list returned videos without stable video_id');
    }
    if (rows.length === 0) {
        throw new EmptyResultError('tiktok creator-videos', 'No creator videos were returned. Confirm the current Chrome profile is logged in to TikTok Studio and has published content.');
    }
    return rows.slice(0, limit);
}

export const creatorVideosCommand = cli({
    site: 'tiktok',
    name: 'creator-videos',
    access: 'read',
    description: 'TikTok Studio creator content list (views/likes/comments/saves/shares)',
    domain: 'www.tiktok.com',
    strategy: Strategy.COOKIE,
    browser: true,
    navigateBefore: STUDIO_CONTENT_URL,
    args: [
        { name: 'limit', type: 'int', default: DEFAULT_LIMIT, help: `Number of creator videos to return (max ${MAX_LIMIT})` },

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Update this library — a schema change in TikTok's item_list response usually needs a parser fix
  2. Log one raw item payload to check which id field is actually present (id vs video_id vs aweme_id)
  3. Exclude drafts/pending posts from the query — some may legitimately lack ids
  4. Report the raw item shape to the maintainers if the schema changed

Example fix

// before
const id = item.video_id;
// after
const id = item.video_id || item.id || item.aweme_id;
if (id) rows.push({ id, ... }); else skippedMissingId++;
Defensive patterns

Strategy: validation

Validate before calling

// Sanity-check one raw item has an id before bulk pagination
const probe = await listCreatorVideos(page, { limit: 1 });
if (!probe[0]?.id) throw new Error('item_list item shape changed: no id field');

Type guard

function hasVideoId(item) { return !!item && typeof item === 'object' && typeof (item.video_id || item.id || item.aweme_id) === 'string'; }

Try / catch

try {
  rows = await listCreatorVideos(page, opts);
} catch (e) {
  if (/without stable video_id/.test(e.message)) {
    console.error('TikTok item_list schema changed — update the CLI library');
  }
  throw e;
}

Prevention

When it happens

Trigger: items were returned by item_list but each item's video_id/id field was missing or unstable (e.g. TikTok renamed the id field or moved it into a nested object), causing all items to be skipped.

Common situations: TikTok changed the item_list JSON schema (id key renamed/moved), draft/scheduled posts lacking ids, or a regional API variant returning a different item shape.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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