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

  1. Log the full response body (the error already embeds 300 chars) and check d.status / d.message for the real reason
  2. Refresh Instagram session cookies and retry the delete
  3. Verify the collection still exists; if already deleted, treat this as idempotent success
  4. 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

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


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