jackwener/OpenCLI · error · CommandExecutionError
Instagram private publish ${stage} returned invalid JSON
Error message
Instagram private publish ${stage} returned invalid JSON What it means
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.
Source
Thrown at clis/instagram/_shared/private-publish.js:751
'X-Entity-Length': String(asset.coverImage.byteLength),
'X-Entity-Name': `fb_uploader_${uploadId}`,
'X-Entity-Type': asset.coverImage.mimeType,
'X-Instagram-Rupload-Params': JSON.stringify({
media_type: 2,
upload_id: uploadId,
upload_media_height: asset.height,
upload_media_width: asset.width,
}),
};
}
async function parseJsonResponse(response, stage) {
const text = await response.text();
let data;
try {
data = text ? JSON.parse(text) : {};
}
catch {
throw new CommandExecutionError(`Instagram private publish ${stage} returned invalid JSON`);
}
if (!response.ok) {
const detail = text ? ` ${text.slice(0, 500)}` : '';
throw new CommandExecutionError(`Instagram private publish ${stage} failed: ${response.status}${detail}`);
}
return data;
}
async function fetchPrivateUploadWithRetry(fetcher, url, init) {
let lastError;
for (let attempt = 0; attempt < INSTAGRAM_PRIVATE_UPLOAD_RETRY_BUDGET; attempt += 1) {
try {
return await fetcher(url, init);
}
catch (error) {
lastError = error;
if (!isTransientPrivateFetchError(error) || attempt >= INSTAGRAM_PRIVATE_UPLOAD_RETRY_BUDGET - 1) {
throw error;
}View on GitHub (pinned to 49907e53dc)
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
Example fix
// before
const data = await parseJsonResponse(response, 'upload');
// after
try { const data = await parseJsonResponse(response, 'upload'); }
catch (e) { if (/invalid JSON/.test(e.message)) console.error('server said:', (await response.text?.()) ?? e.detail); throw e; } Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
const isInvalidJsonError = (e) => e instanceof CommandExecutionError && /returned invalid JSON/.test(e.message);
Try / catch
try { return await publish(input); }
catch (e) {
if (isInvalidJsonError(e)) {
await sleep(5000);
return publish(input); // retry once; if persistent, session is likely expired
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Flomo API returned malformed JSON: ${err instanceof Error ?
- 12306 queryByTrainNo returned non-JSON body
- 12306 ${endpoint} returned non-JSON body
- coingecko derivatives returned malformed JSON: ${err?.messag
- coingecko global returned malformed JSON: ${err?.message ??
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/2aa94d64f782144c.
Report an issue: GitHub.