{"record":{"id":"2aa94d64f782144c","repo":"jackwener/OpenCLI","slug":"instagram-private-publish-stage-returned-invali","errorCode":null,"errorMessage":"Instagram private publish ${stage} returned invalid JSON","messagePattern":"Instagram private publish (.+?) returned invalid JSON","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/instagram/_shared/private-publish.js","lineNumber":751,"sourceCode":"        'X-Entity-Length': String(asset.coverImage.byteLength),\n        'X-Entity-Name': `fb_uploader_${uploadId}`,\n        'X-Entity-Type': asset.coverImage.mimeType,\n        'X-Instagram-Rupload-Params': JSON.stringify({\n            media_type: 2,\n            upload_id: uploadId,\n            upload_media_height: asset.height,\n            upload_media_width: asset.width,\n        }),\n    };\n}\nasync function parseJsonResponse(response, stage) {\n    const text = await response.text();\n    let data;\n    try {\n        data = text ? JSON.parse(text) : {};\n    }\n    catch {\n        throw new CommandExecutionError(`Instagram private publish ${stage} returned invalid JSON`);\n    }\n    if (!response.ok) {\n        const detail = text ? ` ${text.slice(0, 500)}` : '';\n        throw new CommandExecutionError(`Instagram private publish ${stage} failed: ${response.status}${detail}`);\n    }\n    return data;\n}\nasync function fetchPrivateUploadWithRetry(fetcher, url, init) {\n    let lastError;\n    for (let attempt = 0; attempt < INSTAGRAM_PRIVATE_UPLOAD_RETRY_BUDGET; attempt += 1) {\n        try {\n            return await fetcher(url, init);\n        }\n        catch (error) {\n            lastError = error;\n            if (!isTransientPrivateFetchError(error) || attempt >= INSTAGRAM_PRIVATE_UPLOAD_RETRY_BUDGET - 1) {\n                throw error;\n            }","sourceCodeStart":733,"sourceCodeEnd":769,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/instagram/_shared/private-publish.js#L733-L769","documentation":"parseJsonResponse expects the Instagram API response body to be valid JSON; when the body is non-empty but unparseable it throws this error (clis/instagram/_shared/private-publish.js:751). It indicates the endpoint returned HTML, an empty-ish proxy error page, or some other non-JSON payload while the HTTP layer looked fine to fetch.","triggerScenarios":"Any private publish stage (upload, video upload, video cover upload, sidecar publish) where response.text() returns a non-JSON string that JSON.parse rejects — e.g. an HTML login page, a rate-limit page, or a CDN error body.","commonSituations":"Instagram serving an HTML challenge/login redirect because the session cookie expired; corporate proxies or captive portals returning HTML; hitting the wrong endpoint after an API change; response body compressed/mangled by an intermediary proxy.","solutions":["Refresh or re-export your Instagram session cookies — the old session is likely being redirected to an HTML login page","Log the raw response text (first ~500 chars) to see what the server actually returned","Check for proxy/VPN interference and retry from a clean network","Retry later — transient Instagram-side error pages often resolve"],"exampleFix":"// before\nconst data = await parseJsonResponse(response, 'upload');\n// after\ntry { const data = await parseJsonResponse(response, 'upload'); }\ncatch (e) { if (/invalid JSON/.test(e.message)) console.error('server said:', (await response.text?.()) ?? e.detail); throw e; }","handlingStrategy":"retry","validationCode":"null","typeGuard":"const isInvalidJsonError = (e) => e instanceof CommandExecutionError && /returned invalid JSON/.test(e.message);","tryCatchPattern":"try { return await publish(input); }\ncatch (e) {\n  if (isInvalidJsonError(e)) {\n    await sleep(5000);\n    return publish(input); // retry once; if persistent, session is likely expired\n  }\n  throw e;\n}","preventionTips":["Keep Instagram session cookies fresh — expired sessions cause HTML redirects","Avoid proxies/captive portals between the CLI and Instagram","Check session validity with a lightweight authenticated GET before publishing","Log raw response bodies to distinguish transient pages from permanent breakage"],"tags":["network","json-parsing","instagram-api","http-response"],"backgroundTag":"invalid-json-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}