jackwener/OpenCLI · error · CommandExecutionError

TikTok Studio item_list returned an empty response

Error message

TikTok Studio item_list returned an empty response

What it means

unwrapPayload checks the JSON body returned by TikTok Studio's item_list endpoint. If the response is null, undefined, or not an object, the library throws CommandExecutionError because it cannot extract data from an empty body. This guards against proxy/CDN error pages, empty 200 responses, or HTML returned instead of JSON.

Source

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

  } catch (error) {
    return {
      ok: false,
      status: 0,
      statusText: '',
      networkError: error instanceof Error ? error.message : String(error),
    };
  }
})()
`;
}

function looksAuthFailure(message) {
    return /\b(auth|login|log in|permission|unauthori[sz]ed|forbidden)\b/i.test(message);
}

function unwrapPayload(data) {
    if (!data || typeof data !== 'object') {
        throw new CommandExecutionError('TikTok Studio item_list returned an empty response');
    }
    return data.data && typeof data.data === 'object' ? data.data : data;
}

function assertApiSuccess(data) {
    const statusCode = data.status_code ?? data.statusCode;
    const statusMsg = String(data.status_msg ?? data.statusMsg ?? '').trim();
    if (statusCode !== undefined && Number(statusCode) !== 0) {
        if (looksAuthFailure(statusMsg)) {
            throw new AuthRequiredError('www.tiktok.com', `TikTok Studio item_list requires login: ${statusMsg || statusCode}`);
        }
        throw new CommandExecutionError(`TikTok Studio item_list failed: ${statusMsg || statusCode}`);
    }
    if (statusMsg && !/^(success|ok)$/i.test(statusMsg)) {
        if (looksAuthFailure(statusMsg)) {
            throw new AuthRequiredError('www.tiktok.com', `TikTok Studio item_list requires login: ${statusMsg}`);
        }
        throw new CommandExecutionError(`TikTok Studio item_list failed: ${statusMsg}`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry the command once — empty bodies are often transient.
  2. Verify you are logged in (`opencli tiktok login` / refresh cookies) since logged-out sessions can get empty responses.
  3. Check for proxies/VPNs intercepting traffic and return non-JSON bodies.
  4. Inspect the raw response (curl with the same cookies) to see what the server actually returned.

Example fix

// before
const page = await fetchCreatorVideosPage(...); // throws on empty body
// after
try {
  const page = await fetchCreatorVideosPage(...);
} catch (e) {
  if (String(e.message).includes('empty response')) {
    await sleep(2000);
    return fetchCreatorVideosPage(...); // single retry for transient empty body
  }
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

const res = await fetch(studioItemListUrl, { headers });
const text = await res.text();
if (!text.trim()) throw new Error('Empty body from item_list; check login/proxy');
const data = JSON.parse(text);
if (!data || typeof data !== 'object') throw new Error('item_list returned non-object body');

Type guard

const isPayloadObject = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);

Try / catch

try {
  const videos = await listCreatorVideos(opts);
} catch (e) {
  if (String(e.message).includes('empty response')) {
    await sleep(2000);
    const videos = await listCreatorVideos(opts); // one retry
  } else throw e;
}

Prevention

When it happens

Trigger: fetchCreatorVideosPage receives a non-object body (empty string parsed to null, HTML error page, or empty 200 response) from the TikTok Studio item_list request.

Common situations: Being behind a captive portal or corporate proxy returning an empty/HTML body; TikTok rate limiting with an empty response; expired session where the server returns a bare 200 with no body; intermittent network truncation.

Related errors


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