{"record":{"id":"e868b2e3b4e692b1","repo":"jackwener/OpenCLI","slug":"instagram-private-publish-stage-failed-respo","errorCode":null,"errorMessage":"Instagram private publish ${stage} failed: ${response.status}${detail}","messagePattern":"Instagram private publish (.+?) failed: (.+?)(.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/instagram/_shared/private-publish.js","lineNumber":755,"sourceCode":"            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            }\n        }\n    }\n    throw lastError instanceof Error ? lastError : new Error(String(lastError));\n}","sourceCodeStart":737,"sourceCodeEnd":773,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/instagram/_shared/private-publish.js#L737-L773","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the `detail` in the message — the response body usually names the exact problem (e.g. 'login_required', 'rate limit')","Refresh your Instagram session cookies / re-login before retrying","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)","Reduce publish frequency and randomize timing to avoid rate limiting"],"exampleFix":"// before\ncatch (e) { console.error(e.message); }\n// after\ncatch (e) {\n  const m = /failed: (\\d{3})/.exec(e.message);\n  if (m && (m[1] === '429' || m[1][0] === '5')) { await new Promise(r => setTimeout(r, 60000)); return publish(input); }\n  if (m && (m[1] === '401' || m[1] === '403')) throw new Error('Session expired — refresh Instagram cookies');\n  throw e;\n}","handlingStrategy":"retry","validationCode":"null","typeGuard":"const statusOf = (e) => { const m = /failed: (\\d{3})/.exec(e.message); return m ? Number(m[1]) : null; };","tryCatchPattern":"try { return await publish(input); }\ncatch (e) {\n  const s = statusOf(e);\n  if (s === 429 || (s && s >= 500)) { await sleep(60000); return publish(input); }\n  if (s === 401 || s === 403) throw new Error('Instagram session expired — refresh cookies');\n  throw e;\n}","preventionTips":["Throttle publish frequency to avoid 429 rate limits","Refresh session cookies on 401/403 instead of retrying blindly","Parse the message `detail` (first 500 chars of body) for Instagram's reason","Monitor for Instagram private API changes after app updates"],"tags":["network","http-status","instagram-api","rate-limit"],"backgroundTag":"http-request-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}