jackwener/OpenCLI · error · CommandExecutionError

Instagram private publish ${stage} failed: ${response.status

Error message

Instagram private publish ${stage} failed: ${response.status}${detail}

What it means

After successfully parsing the JSON body, parseJsonResponse checks response.ok; when the status is non-2xx it throws this error with the status code and up to 500 characters of the body (clis/instagram/_shared/private-publish.js:755). It is the generic HTTP failure point for every private publish stage against Instagram's web/private API.

Source

Thrown at clis/instagram/_shared/private-publish.js:755

            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;
            }
        }
    }
    throw lastError instanceof Error ? lastError : new Error(String(lastError));
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the `detail` in the message — the response body usually names the exact problem (e.g. 'login_required', 'rate limit')
  2. Refresh your Instagram session cookies / re-login before retrying
  3. Back off and retry after a delay if the status is 429 or 5xx (the library retries uploads via fetchPrivateUploadWithRetry, but publish calls may not)
  4. Reduce publish frequency and randomize timing to avoid rate limiting

Example fix

// before
catch (e) { console.error(e.message); }
// after
catch (e) {
  const m = /failed: (\d{3})/.exec(e.message);
  if (m && (m[1] === '429' || m[1][0] === '5')) { await new Promise(r => setTimeout(r, 60000)); return publish(input); }
  if (m && (m[1] === '401' || m[1] === '403')) throw new Error('Session expired — refresh Instagram cookies');
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

const statusOf = (e) => { const m = /failed: (\d{3})/.exec(e.message); return m ? Number(m[1]) : null; };

Try / catch

try { return await publish(input); }
catch (e) {
  const s = statusOf(e);
  if (s === 429 || (s && s >= 500)) { await sleep(60000); return publish(input); }
  if (s === 401 || s === 403) throw new Error('Instagram session expired — refresh cookies');
  throw e;
}

Prevention

When it happens

Trigger: Any fetch during private publish returning 4xx/5xx: 401/403 from expired or invalid session cookies, 429 rate limiting after repeated uploads, 5xx Instagram server errors, 400 from malformed upload payloads.

Common situations: Session cookie expired; account flagged for automated behavior; uploading too frequently (rate limit); Instagram changed the private endpoint or required new headers; wrong csrf/APP header values.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/e868b2e3b4e692b1. Report an issue: GitHub.