{"record":{"id":"47d30f9f04bae823","repo":"jackwener/OpenCLI","slug":"could-not-fetch-lists-listsdata-error-47d30f","errorCode":null,"errorMessage":"Could not fetch lists: ${listsData.__error}","messagePattern":"Could not fetch lists: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/twitter/list-delete.js","lineNumber":56,"sourceCode":"    longform_notetweets_inline_media_enabled: true,\n    responsive_web_grok_image_annotation_enabled: true,\n    responsive_web_enhance_cards_enabled: false,\n};\n\nfunction normalizeConfirm(value) {\n    return value === true || value === 'true';\n}\n\nasync function getManagedLists(page, headers) {\n    const listsQueryId = await resolveTwitterQueryId(page, 'ListsManagementPageTimeline', LISTS_MANAGEMENT_QUERY_ID);\n    const listsUrl = `/i/api/graphql/${listsQueryId}/ListsManagementPageTimeline?features=${encodeURIComponent(JSON.stringify(LISTS_MANAGEMENT_FEATURES))}`;\n    const listsData = unwrapBrowserResult(await page.evaluate(`async () => {\n        const r = await fetch(${JSON.stringify(listsUrl)}, { headers: ${headers}, credentials: 'include' });\n        if (!r.ok) return { __error: 'HTTP ' + r.status };\n        return await r.json();\n    }`));\n    if (listsData && listsData.__error) {\n        throw new CommandExecutionError(`Could not fetch lists: ${listsData.__error}`);\n    }\n    return parseListsManagement(listsData, new Set());\n}\n\nexport function buildListDeleteRow({ listId, targetList }) {\n    return {\n        listId,\n        name: targetList.name,\n        members: String(targetList.members ?? '0'),\n        status: 'success',\n        message: `Deleted list ${targetList.name} (${targetList.members ?? '0'} members)`,\n    };\n}\n\ncli({\n    site: 'twitter',\n    name: 'list-delete',\n    access: 'write',","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/list-delete.js#L38-L74","documentation":"getManagedLists fetches the user's lists via an in-page fetch of Twitter's ListsManagement endpoint. When the HTTP response is not ok, the evaluate returns { __error: 'HTTP <status>' }, which the function converts into CommandExecutionError. This means the lists could not be retrieved, so delete-time verification cannot proceed.","triggerScenarios":"The in-page fetch of listsUrl returns a non-2xx status (r.ok false) — 401/403 from expired auth, 404 from a changed GraphQL queryId/endpoint, 429 rate limit — producing listsData.__error.","commonSituations":"Session/csrf token expired mid-run; Twitter changed the ListsManagement queryId so the endpoint 404s; hitting rate limits from repeated list operations; network/proxy blocking x.com API calls.","solutions":["Re-authenticate (log into x.com) and retry — HTTP 401/403 is the most common cause","Check the status code in the message: 429 means slow down / wait before retrying; 404 means the endpoint/queryId changed and the code needs updating","Verify the Bearer token and ct0 csrf header are current","Retry after a backoff; check network/proxy access to x.com"],"exampleFix":"// before\nawait getManagedLists(page, headers);\n// after\ntry {\n  const lists = await getManagedLists(page, headers);\n} catch (e) {\n  await page.goto('https://x.com'); await page.wait(3); // refresh ct0\n  const lists = await getManagedLists(page, headers);\n}","handlingStrategy":"retry","validationCode":"const cookies = await page.getCookies({ url: 'https://x.com' });\nif (!cookies.some((c) => c.name === 'ct0')) throw new Error('Refresh session before fetching lists');","typeGuard":"function isListsPayload(d) {\n  return d && typeof d === 'object' && !d.__error && (Array.isArray(d.data?.lists_by_name?.lists) || Array.isArray(d.lists));\n}","tryCatchPattern":"try {\n  const lists = await getManagedLists(page, headers);\n} catch (e) {\n  if (/Could not fetch lists: HTTP 429/.test(e.message)) await sleep(60000);\n  else if (/HTTP 40[13]/.test(e.message)) await refreshLogin();\n  throw e;\n}","preventionTips":["Refresh ct0 before long batch runs","Back off on 429s; re-auth on 401/403","Update queryId/endpoint when 404s appear after Twitter deploys changes"],"tags":["http","network","twitter-graphql"],"backgroundTag":"http-error-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}