jackwener/OpenCLI · error · Error
HTTP ${res.status} from ${requestUrl}: ${text.slice(0, 160)}
Error message
HTTP ${res.status} from ${requestUrl}: ${text.slice(0, 160)} What it means
The TikTok API fetch helper treats any non-2xx response as fatal and throws an Error containing the status code, the requested URL, and the first 160 characters of the response body. This surfaces server-side rejections (403, 4xx/5xx) with enough of the body to diagnose them.
Source
Thrown at clis/tiktok/utils.js:238
}
function getCookie(name) {
const prefix = name + '=';
for (const part of (document.cookie || '').split('; ')) {
if (part.startsWith(prefix)) return decodeURIComponent(part.slice(prefix.length));
}
return '';
}
async function fetchJson(url) {
const requestUrl = new URL(url, ${JSON.stringify(TIKTOK_HOST)}).toString();
const res = await fetch(requestUrl, {
credentials: 'include',
headers: { accept: 'application/json,text/plain,*/*' },
});
const text = await res.text();
if (!res.ok) {
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);View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect the 160-char body snippet: an HTML challenge means cookies/IP are blocked — refresh session cookies
- Retry with backoff for 5xx/429 statuses
- Route requests through a residential proxy or different IP
- Confirm the API URL is still valid (404 suggests a TikTok endpoint change)
Example fix
// before
const res = await fetch(requestUrl, { credentials: 'include' });
if (!res.ok) throw new Error('HTTP ' + res.status + ' ...');
// after
if (res.status === 429 || res.status >= 500) {
await sleep(2000); return fetchJson(requestUrl); // retry once
}
if (!res.ok) throw new Error('HTTP ' + res.status + ' ...'); Defensive patterns
Strategy: retry
Validate before calling
// pre-check session validity before API calls
const ok = await page.evaluate(() => document.cookie.includes('sessionid'));
if (!ok) throw new Error('TikTok session cookies missing — login first'); Type guard
function isHttpError(e) { return /^HTTP \d{3} from /.test(e?.message || ''); }
function statusCodeOf(e) { const m = e?.message.match(/^HTTP (\d{3})/); return m ? Number(m[1]) : null; } Try / catch
try { const data = await fetchJson(url); } catch (e) {
const status = statusCodeOf(e);
if (status === 429 || (status && status >= 500)) { await backoff(); return fetchJson(url); }
throw e;
} Prevention
- Check cookie validity before issuing API calls
- Back off on 429/5xx instead of failing the whole run
- Use residential IPs to avoid WAF blocks
- Log the body snippet to classify HTML challenge vs server error
When it happens
Trigger: fetchJson to a tiktok.com API endpoint returned res.ok === false — e.g. expired cookies causing 403, rate limiting returning 429, or a 500 from TikTok's backend.
Common situations: Session cookies expired or missing (403 with an HTML challenge page), datacenter IP blocked by TikTok WAF, transient 5xx, or the endpoint URL changed and now 404s.
Related errors
- ${label} returned HTTP ${resp.status}: ${summarizeApiError(p
- HTTP ${result.httpStatus} from /api/organizations
- ${label} returned HTTP ${res.status}
- HTTP_ERROR
- HTTP_ERROR
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/2804b6f8c2af04a7.
Report an issue: GitHub.