jackwener/OpenCLI · error
Instagram returned non-ok status: ${JSON.stringify(d).slice(
Error message
Instagram returned non-ok status: ${JSON.stringify(d).slice(0, 300)} What it means
Thrown after a successful HTTP DELETE of an Instagram collection when the JSON body contains a 'status' field that is not 'ok'. Instagram sometimes returns HTTP 200 with an in-body error status, so the CLI inspects the parsed payload and surfaces the first 300 chars of it. It means the API acknowledged the request but did not confirm success.
Source
Thrown at clis/instagram/collection-delete.js:82
id = String(matches[0].collection_id);
resolvedName = String(matches[0].collection_name || raw);
}
const fd = new FormData();
fd.append('module_name', 'collection_settings');
const res = await fetch('https://www.instagram.com/api/v1/collections/' + encodeURIComponent(id) + '/delete/', {
method: 'POST',
credentials: 'include',
headers: { ...headers, 'X-CSRFToken': csrf },
body: fd,
});
if (!res.ok) {
const body = await res.text().catch(() => '');
throw new Error('Failed to delete collection: HTTP ' + res.status + (body ? ' - ' + body.slice(0, 200) : ''));
}
const d = await res.json().catch(() => ({}));
if (d?.status && d.status !== 'ok') {
throw new Error('Instagram returned non-ok status: ' + JSON.stringify(d).slice(0, 300));
}
return [{
status: 'Deleted',
collectionId: id,
collectionName: resolvedName,
}];
})()
` },
],
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Log the full response body (the error already embeds 300 chars) and check d.status / d.message for the real reason
- Refresh Instagram session cookies and retry the delete
- Verify the collection still exists; if already deleted, treat this as idempotent success
- Retry after a backoff if the status indicates rate limiting or transient failure
Example fix
// before
if (d?.status && d.status !== 'ok') {
throw new Error('Instagram returned non-ok status: ' + JSON.stringify(d).slice(0, 300));
}
// after
if (d?.status && d.status !== 'ok') {
if (d.status === 'fail' && /already deleted|not found/i.test(d.message || '')) {
return [{ status: 'Deleted', collectionId: id, collectionName: resolvedName }];
}
throw new Error('Instagram returned non-ok status: ' + JSON.stringify(d).slice(0, 300));
} Defensive patterns
Strategy: validation
Validate before calling
const d = await res.json().catch(() => ({}));
if (d?.status && d.status !== 'ok') {
console.error('Delete not confirmed:', JSON.stringify(d));
// treat as failure or check whether collection already gone before rethrowing
} Type guard
function isOkStatus(d) {
return !!d && typeof d === 'object' && (d.status === undefined || d.status === 'ok');
} Try / catch
try {
await deleteCollection(id, name);
} catch (e) {
if (/non-ok status/.test(e.message)) {
// inspect embedded JSON body, refresh cookies, retry once
} else throw e;
} Prevention
- Keep Instagram session cookies fresh
- Check response body status fields even when HTTP 200
- Treat already-deleted collections as success for idempotency
- Rate-limit destructive calls to avoid soft blocks
When it happens
Trigger: DELETE /api/v1/collections/{id}/delete/ returns 200 with body {"status":"fail"} or similar; session/CSRF issues, rate limiting, or Instagram soft-blocking the collection delete while returning HTTP 200.
Common situations: Stale or partially-invalid session cookies causing IG to reject the mutation in-body; deleting a collection that was already removed via the app; Instagram A/B responses where the operation was not applied.
Related errors
- coingecko returned malformed JSON: ${error?.message || error
- coingecko global returned no data envelope
- coingecko returned an unexpected response
- Instagram whoami failed: ${result.detail}
- ${label} returned malformed items payload
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/fe047e27408ee691.
Report an issue: GitHub.