{"record":{"id":"5921042cfcd03aca","repo":"jackwener/OpenCLI","slug":"returned-invalid-json","errorCode":null,"errorMessage":" returned invalid JSON","messagePattern":" returned invalid JSON","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"clis/instagram/save.js","lineNumber":30,"sourceCode":"            positional: true,\n            help: 'Username of the post author',\n        },\n        { name: 'index', type: 'int', default: 1, help: 'Post index (1 = most recent)' },\n    ],\n    columns: ['status', 'user', 'post'],\n    pipeline: [\n        { navigate: 'https://www.instagram.com' },\n        { evaluate: `(async () => {\n  const username = \\${{ args.username | json }};\n  const idx = \\${{ args.index }} - 1;\n  if (!Number.isInteger(idx) || idx < 0) throw new Error('index must be a positive integer');\n  const headers = { 'X-IG-App-ID': '936619743392459' };\n  const opts = { credentials: 'include', headers };\n  async function readInstagramJson(response, label) {\n    try {\n      return await response.json();\n    } catch {\n      throw new Error(label + ' returned invalid JSON');\n    }\n  }\n  function getPostFromFeed(feed, label) {\n    if (!feed || typeof feed !== 'object' || !Array.isArray(feed.items)) {\n      throw new Error(label + ' returned malformed items payload');\n    }\n    if (idx >= feed.items.length) throw new Error('Post index ' + (idx + 1) + ' not found');\n    const post = feed.items[idx];\n    const pkRaw = post?.pk ?? post?.id;\n    const pk = typeof pkRaw === 'number' ? String(pkRaw) : (typeof pkRaw === 'string' ? pkRaw.trim() : '');\n    if (!/^\\\\d+$/.test(pk)) throw new Error(label + ' returned malformed post row');\n    const caption = typeof post?.caption?.text === 'string' ? post.caption.text.substring(0, 60) : '';\n    return { pk, caption };\n  }\n  function assertOkStatus(payload, label) {\n    if (!payload || typeof payload !== 'object' || payload.status !== 'ok') {\n      throw new Error(label + ' returned no success evidence');\n    }","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/instagram/save.js#L12-L48","documentation":"The `readInstagramJson` helper wraps `response.json()` for Instagram API responses; when the body cannot be parsed as JSON, it rethrows with the endpoint label plus this message (e.g. 'Instagram feed-by-username returned invalid JSON'). Instagram frequently returns HTML (login pages, rate-limit/challenge pages) with an HTTP 200, so this error surfaces whenever the feed-by-username or save endpoint's body is not JSON.","triggerScenarios":"Calling GET /api/v1/feed/user/<username>/username/ or POST /api/v1/web/save/<pk>/save/ from an authenticated browser context where the response body is HTML instead of JSON: a session-expiry redirect to the login page, a rate-limit/challenge interstitial, or an empty/HTML error page returned with status 200.","commonSituations":"Instagram session cookies have expired so the fetch lands on the login HTML page; the account hit a rate limit or 'Try again later' challenge; a proxy/corporate gateway intercepts the request and returns an HTML block page; Instagram A/B changes the response shape or returns an empty body on 200.","solutions":["Re-login to Instagram in the browser profile the CLI drives (refresh the session cookies), then retry.","Wait and retry later if rate-limited — the response is a challenge/HTML page, not JSON.","Check whether a proxy, VPN, or corporate firewall is intercepting requests to instagram.com and returning HTML.","Retry the command once; transient HTML error pages sometimes resolve on a second attempt."],"exampleFix":"// trigger a fresh login before running the command\n// before\ninstagram save someuser --index 1  // -> 'Instagram feed-by-username returned invalid JSON'\n// after\nopen browser profile -> log into instagram.com -> retry:\ninstagram save someuser --index 1","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await run(['instagram', 'save', username, '--index', String(i)]);\n} catch (e) {\n  if (String(e.message).includes('returned invalid JSON')) {\n    // session likely expired or HTML challenge page returned\n    await refreshInstagramLogin();\n    return retryWithBackoff(() => run(['instagram', 'save', username, '--index', String(i)]), { attempts: 2 });\n  }\n  throw e;\n}","preventionTips":["Keep the CLI browser profile's Instagram session fresh; re-login periodically.","Don't loop the command rapidly — rate limits cause HTML challenge pages.","Disable interfering proxies/VPN for instagram.com traffic."],"tags":["network","json","instagram","authentication"],"backgroundTag":"invalid-json-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}