{"record":{"id":"2804b6f8c2af04a7","repo":"jackwener/OpenCLI","slug":"http-res-status-from-requesturl-text-slic","errorCode":null,"errorMessage":"HTTP ${res.status} from ${requestUrl}: ${text.slice(0, 160)}","messagePattern":"HTTP (.+?) from (.+?): (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/tiktok/utils.js","lineNumber":238,"sourceCode":"}\n\nfunction getCookie(name) {\n  const prefix = name + '=';\n  for (const part of (document.cookie || '').split('; ')) {\n    if (part.startsWith(prefix)) return decodeURIComponent(part.slice(prefix.length));\n  }\n  return '';\n}\n\nasync function fetchJson(url) {\n  const requestUrl = new URL(url, ${JSON.stringify(TIKTOK_HOST)}).toString();\n  const res = await fetch(requestUrl, {\n    credentials: 'include',\n    headers: { accept: 'application/json,text/plain,*/*' },\n  });\n  const text = await res.text();\n  if (!res.ok) {\n    throw new Error('HTTP ' + res.status + ' from ' + requestUrl + ': ' + text.slice(0, 160));\n  }\n  if (!text.trim()) return {};\n  try {\n    return JSON.parse(text);\n  } catch (error) {\n    throw new Error('invalid JSON from ' + requestUrl + ': ' + (error instanceof Error ? error.message : String(error)));\n  }\n}\n\nfunction assertTikTokApiSuccess(data, label) {\n  if (!data || typeof data !== 'object') return;\n  const code = data.status_code ?? data.statusCode;\n  if (code === undefined || code === null || Number(code) === 0) return;\n  const message = cleanText(data.status_msg ?? data.statusMsg ?? data.message ?? data.msg ?? code, 240);\n  if (Number(code) === 8 || /auth|captcha|login|permission|unauthori[sz]ed|forbidden/i.test(message)) {\n    throw new Error('AUTH_REQUIRED: ' + label + ' API failed: ' + message);\n  }\n  throw new Error(label + ' API failed: ' + message);","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/tiktok/utils.js#L220-L256","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\nconst res = await fetch(requestUrl, { credentials: 'include' });\nif (!res.ok) throw new Error('HTTP ' + res.status + ' ...');\n// after\nif (res.status === 429 || res.status >= 500) {\n  await sleep(2000); return fetchJson(requestUrl); // retry once\n}\nif (!res.ok) throw new Error('HTTP ' + res.status + ' ...');","handlingStrategy":"retry","validationCode":"// pre-check session validity before API calls\nconst ok = await page.evaluate(() => document.cookie.includes('sessionid'));\nif (!ok) throw new Error('TikTok session cookies missing — login first');","typeGuard":"function isHttpError(e) { return /^HTTP \\d{3} from /.test(e?.message || ''); }\nfunction statusCodeOf(e) { const m = e?.message.match(/^HTTP (\\d{3})/); return m ? Number(m[1]) : null; }","tryCatchPattern":"try { const data = await fetchJson(url); } catch (e) {\n  const status = statusCodeOf(e);\n  if (status === 429 || (status && status >= 500)) { await backoff(); return fetchJson(url); }\n  throw e;\n}","preventionTips":["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"],"tags":["http","network","tiktok","api"],"backgroundTag":"http-non-2xx-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}