jackwener/OpenCLI · error

Failed to create collection: HTTP ${res.status}${body ? ' -

Error message

Failed to create collection: HTTP ${res.status}${body ? ' - ' + body.slice(0, 200) : ''}

What it means

Thrown when the POST to /api/v1/collections/create/ returns a non-2xx HTTP status. The error includes the status code and the first 200 characters of the response body to expose Instagram's reason (rate limit, login required, bad request). It is the generic transport-level failure for the create call.

Source

Thrown at clis/instagram/collection-create.js:43

  const csrf = document.cookie.match(/csrftoken=([^;]+)/)?.[1] || '';
  if (!csrf) {
    throw new Error('csrftoken cookie missing - make sure you are logged in to Instagram');
  }
  const fd = new FormData();
  fd.append('name', trimmed);
  fd.append('module_name', 'collection_create');
  const res = await fetch('https://www.instagram.com/api/v1/collections/create/', {
    method: 'POST',
    credentials: 'include',
    headers: {
      'X-IG-App-ID': '936619743392459',
      'X-CSRFToken': csrf,
    },
    body: fd,
  });
  if (!res.ok) {
    const body = await res.text().catch(() => '');
    throw new Error('Failed to create collection: HTTP ' + res.status + (body ? ' - ' + body.slice(0, 200) : ''));
  }
  const d = await res.json();
  if (d?.status && d.status !== 'ok') {
    throw new Error('Instagram returned non-ok status: ' + JSON.stringify(d).slice(0, 300));
  }
  return [{
    status: 'Created',
    collectionId: String(d?.collection_id ?? ''),
    collectionName: String(d?.collection_name ?? trimmed),
    mediaCount: d?.collection_media_count ?? 0,
  }];
})()
` },
    ],
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the appended body slice to identify Instagram's error reason
  2. Re-authenticate / refresh csrftoken if the body mentions login_required or 403
  3. Wait and retry with backoff if status is 429 (rate limited)
  4. Verify the endpoint is still valid (Instagram private API changes)

Example fix

// before
throw new Error('Failed to create collection: HTTP ' + res.status + ...);
// after
if (res.status === 429) { await sleep(60000); return createCollection(name); } // retry on rate limit
throw new Error('Failed to create collection: HTTP ' + res.status + ...);
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: confirm session is authenticated before calling
const authed = await page.evaluate(() => document.cookie.includes('csrftoken='));
if (!authed) throw new Error('Login required before creating collections');

Type guard

function isAuthedContext(cookies: string): boolean {
  return /(?:^|;\s*)csrftoken=[^;]+/.test(cookies);
}

Try / catch

try {
  await createCollection(name);
} catch (e) {
  const m = String(e.message).match(/HTTP (\d+)/);
  if (m && (m[1] === '401' || m[1] === '403')) { await relogin(); return createCollection(name); }
  if (m && m[1] === '429') { await sleep(60000); return createCollection(name); }
  throw e;
}

Prevention

When it happens

Trigger: Calling the create pipeline with an invalid/expired CSRF token (403), unauthenticated session (401/403), rate limiting (429), Instagram changing the endpoint, or a malformed form payload rejected by the server.

Common situations: Session expired mid-run causing 403 'Please wait a few minutes' or 'login_required' bodies; hitting API rate limits after many rapid creates; Instagram renaming the private API version.

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/a44b07ad970e3d08. Report an issue: GitHub.