{"record":{"id":"4073051930d94398","repo":"jackwener/OpenCLI","slug":"failed-to-list-collections-http-listres-status","errorCode":null,"errorMessage":"Failed to list collections: HTTP ${listRes.status} - make sure you are logged in to Instagram","messagePattern":"Failed to list collections: HTTP (.+?) - make sure you are logged in to Instagram","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"clis/instagram/collection-delete.js","lineNumber":39,"sourceCode":"  if (!target || !String(target).trim()) {\n    throw new Error('Collection target (name or id) cannot be empty');\n  }\n  const raw = String(target).trim();\n  const csrf = document.cookie.match(/csrftoken=([^;]+)/)?.[1] || '';\n  if (!csrf) {\n    throw new Error('csrftoken cookie missing - make sure you are logged in to Instagram');\n  }\n  const headers = { 'X-IG-App-ID': '936619743392459' };\n\n  // Resolve name -> id via /collections/list/. Always go through this path so we can\n  // surface an explicit error on duplicate names or unknown names instead of relying\n  // on a 404.\n  const listRes = await fetch('https://www.instagram.com/api/v1/collections/list/?collection_types=%5B%22MEDIA%22%5D', {\n    credentials: 'include',\n    headers,\n  });\n  if (!listRes.ok) {\n    throw new Error('Failed to list collections: HTTP ' + listRes.status + ' - make sure you are logged in to Instagram');\n  }\n  const listData = await listRes.json();\n  const collections = listData?.items || [];\n  const isNumericId = /^\\\\d{6,}$/.test(raw);\n  let id = '';\n  let resolvedName = '';\n  if (isNumericId) {\n    const hit = collections.find((c) => String(c?.collection_id) === raw);\n    if (!hit) {\n      throw new Error('Collection id not found in your account: ' + raw);\n    }\n    id = String(hit.collection_id);\n    resolvedName = String(hit.collection_name || '');\n  } else {\n    const wanted = raw.toLowerCase();\n    const matches = collections.filter((c) => String(c?.collection_name || '').trim().toLowerCase() === wanted);\n    if (matches.length === 0) {\n      const names = collections.map((c) => c?.collection_name).filter(Boolean);","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/instagram/collection-delete.js#L21-L57","documentation":"Thrown when the GET to /api/v1/collections/list/ used to resolve the target to an id returns non-2xx. The message appends the HTTP status and hints at login problems because the most common cause is an unauthenticated session (401/403). This check runs before any name/id matching.","triggerScenarios":"Expired or invalid session cookies, missing/invalid X-IG-App-ID acceptance, 429 rate limiting on the list endpoint, or Instagram changing the collections/list API, all while resolving the delete target.","commonSituations":"Session expired between login and delete; heavy automation triggering rate limits; Instagram removing/altering the private list endpoint.","solutions":["Log in again to refresh the session cookies","Wait before retrying if status is 429","Check the status code: 401/403 -> auth issue, 429 -> rate limit, 404 -> API change","Verify the request includes credentials: 'include' and the X-IG-App-ID header"],"exampleFix":"// before\nthrow new Error('Failed to list collections: HTTP ' + listRes.status + ...);\n// after\nif (listRes.status === 429) { await sleep(60000); return deleteCollection(target); }\nthrow new Error('Failed to list collections: HTTP ' + listRes.status + ...);","handlingStrategy":"retry","validationCode":"const authed = await page.evaluate(() => document.cookie.includes('csrftoken='));\nif (!authed) throw new Error('Login required before deleting collections');","typeGuard":"function isAuthedContext(cookies: string): boolean {\n  return /(?:^|;\\s*)csrftoken=[^;]+/.test(cookies);\n}","tryCatchPattern":"try {\n  await deleteCollection(target);\n} catch (e) {\n  const m = String(e.message).match(/HTTP (\\d+)/);\n  if (m && m[1] === '429') { await sleep(60000); return deleteCollection(target); }\n  if (m && (m[1] === '401' || m[1] === '403')) { await relogin(); return deleteCollection(target); }\n  throw e;\n}","preventionTips":["Refresh sessions before batch delete operations","Add delays between list/delete calls to avoid rate limits","Map status codes to actions: 401/403 re-login, 429 backoff, 404 API change","Watch for Instagram private-API endpoint changes"],"tags":["http","network","instagram-api","authentication"],"backgroundTag":"http-request-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}