jackwener/OpenCLI · error · CommandExecutionError
Instagram private publish configure_sidecar returned invalid
Error message
Instagram private publish configure_sidecar returned invalid JSON
What it means
publishSidecarWithRetry POSTs to https://www.instagram.com/api/v1/media/configure_sidecar/ and JSON.parses the raw response body. When the body is non-empty but not valid JSON (HTML login page, rate-limit page, proxy interstitial, garbage body), the parse throws and the library converts it into this CommandExecutionError instead of leaking a raw SyntaxError.
Source
Thrown at clis/instagram/_shared/private-publish.js:854
async function publishSidecarWithRetry(input) {
const waitMs = input.waitMs ?? sleep;
const requestInit = {
method: 'POST',
headers: {
...buildPrivateApiHeaders(input.apiContext),
'Content-Type': 'application/json',
},
body: JSON.stringify(input.payload),
};
for (let attempt = 0; attempt < INSTAGRAM_PRIVATE_SIDECAR_TRANSCODE_ATTEMPTS; attempt += 1) {
const response = await input.fetcher('https://www.instagram.com/api/v1/media/configure_sidecar/', requestInit);
const text = await response.text();
let json = {};
try {
json = text ? JSON.parse(text) : {};
}
catch {
throw new CommandExecutionError('Instagram private publish configure_sidecar returned invalid JSON');
}
if (!response.ok) {
const detail = text ? ` ${text.slice(0, 500)}` : '';
throw new CommandExecutionError(`Instagram private publish configure_sidecar failed: ${response.status}${detail}`);
}
const message = String(json?.message || '');
if (response.status === 202
|| /transcode not finished yet/i.test(message)) {
if (attempt >= INSTAGRAM_PRIVATE_SIDECAR_TRANSCODE_ATTEMPTS - 1) {
throw new CommandExecutionError('Instagram private publish configure_sidecar timed out waiting for video transcode', text.slice(0, 500));
}
await waitMs(INSTAGRAM_PRIVATE_SIDECAR_TRANSCODE_WAIT_MS);
continue;
}
if (String(json?.status || '').toLowerCase() === 'fail') {
throw new CommandExecutionError('Instagram private publish configure_sidecar failed', message || text.slice(0, 500));
}
return { code: json?.media?.code };View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect the raw response via fetch interception/debug logging on the configure_sidecar call to see the actual body.
- Refresh the Instagram session cookies / re-login; a stale session is the most common cause of HTML responses.
- Retry after a delay; transient Instagram 5xx or rate-limiting often returns non-JSON bodies.
- Check the network path (proxy/VPN) is not injecting HTML into API responses.
- Verify the request headers built by buildPrivateApiHeaders are correct (missing headers can trigger challenge pages).
Example fix
// before
const text = await response.text();
// after
const text = await response.text();
if (/^\s*</.test(text)) throw new Error('configure_sidecar returned HTML (session expired?): ' + text.slice(0, 200)); Defensive patterns
Strategy: try-catch
Validate before calling
// Sanity-check session before private publish
const cookies = await page.context().cookies('https://www.instagram.com');
if (!cookies.some(c => c.name === 'ds_user_id')) throw new Error('Not logged in — configure_sidecar would return HTML'); Type guard
function isJsonObject(value) {
return typeof value === 'object' && value !== null && !Array.isArray(value);
} Try / catch
try {
await publishMediaViaPrivateApi({ mediaItems, apiContext });
} catch (e) {
if (/returned invalid JSON/.test(e.message)) {
await refreshInstagramSession(page); // HTML body usually means dead session
await publishMediaViaPrivateApi({ mediaItems, apiContext });
} else throw e;
} Prevention
- Verify session cookies (ds_user_id, csrftoken) exist before private API calls.
- Publish from residential IPs to avoid challenge pages.
- Log raw response bodies on failure for diagnosis.
- Back off and retry on transient Instagram 5xx.
When it happens
Trigger: The configure_sidecar HTTP response has a non-empty body that fails JSON.parse — e.g. Instagram returned an HTML login/challenge page, a Cloudflare/proxy block page, or truncated/garbage text instead of the expected JSON envelope.
Common situations: Expired or invalid session cookies so the private API returns the login HTML page; datacenter IP blocked by Instagram returning a challenge page; corporate proxy injecting HTML; transient 5xx returning an HTML error page.
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
- ${label} returned invalid JSON
- Instagram private route could not derive X-IG-App-ID from in
- Instagram private route could not derive X-Instagram-AJAX fr
- Instagram private publish configure_sidecar failed: ${respon
- ${label} returned invalid JSON
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/8a73e00a29f2ea5b.
Report an issue: GitHub.