{"record":{"id":"9c4bf884a40043dd","repo":"jackwener/OpenCLI","slug":"could-not-verify-list-removal-list-listid-miss","errorCode":null,"errorMessage":"Could not verify list removal: list ${listId} missing from post-delete payload","messagePattern":"Could not verify list removal: list (.+?) missing from post-delete payload","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"warning","filePath":"clis/twitter/list-remove-core.js","lineNumber":251,"sourceCode":"            await page.nativeClick(uiResult.rowClickX, uiResult.rowClickY);\n            await new Promise((r) => setTimeout(r, 800));\n            await page.nativeClick(uiResult.saveClickX, uiResult.saveClickY);\n            await new Promise((r) => setTimeout(r, 3500));\n            const listsAfter = 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 (listsAfter && listsAfter.__error) {\n                throw new CommandExecutionError(`Could not verify list removal: ${listsAfter.__error}`);\n            }\n            if (!getListsManagementInstructions(listsAfter)) {\n                throw new CommandExecutionError('Could not verify list removal: unexpected lists payload shape');\n            }\n            const parsedAfter = parseListsManagement(listsAfter, new Set());\n            const afterList = parsedAfter.find((l) => l.id === listId);\n            if (!afterList) {\n                throw new CommandExecutionError(`Could not verify list removal: list ${listId} missing from post-delete payload`);\n            }\n            const memberCountAfter = Number(afterList.members) || 0;\n            if (memberCountAfter < memberCountBefore) {\n                verifiedBy = `member_count ${memberCountBefore} → ${memberCountAfter}`;\n            } else {\n                throw new CommandExecutionError(`Failed to remove @${username} from list ${listId}: member_count unchanged (${memberCountBefore} → ${memberCountAfter}).`);\n            }\n        }\n\n    return [{\n        listId,\n        username,\n        userId: String(userId),\n        status: uiResult.noop ? 'noop' : 'success',\n        message: uiResult.noop\n            ? `@${username} was not a member of list ${listId}`\n            : `Removed @${username} from list ${listId} (verified via ${verifiedBy})`,\n    }];","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/list-remove-core.js#L233-L269","documentation":"Verification parsed the post-delete lists payload but the list with the requested listId was absent from it. The library cannot confirm the member_count drop (its chosen verification signal) without that list's entry, so it throws rather than claiming success.","triggerScenarios":"After the Save click, parseListsManagement ran over the fresh payload and .find(l => l.id === listId) returned undefined — e.g. the payload is paginated and the list fell on a later page not fetched, or the list was deleted/renamed between the pre-check and verification.","commonSituations":"Accounts with many lists where the target list is beyond the first page of the management timeline; the list was deleted concurrently; listId passed as a differently-formatted string (id coercion mismatch between pre- and post-parse).","solutions":["Reduce the account's list count or verify manually — the removal likely succeeded but the list is simply not in the fetched page","Re-run the command; pagination order can shift after mutations","Confirm the list still exists via `opencli twitter lists` and that listId matches exactly (numeric string)","If it recurs, file a bug: verification should paginate or treat a missing list as 'deleted/unknown' instead of erroring"],"exampleFix":"// before\nconst out = await listRemoveUser(page, { listId, username });\n// after\ntry {\n  const out = await listRemoveUser(page, { listId, username });\n} catch (e) {\n  if (e.message.includes('missing from post-delete payload')) {\n    const stillThere = (await runTwitterCommand('lists', {})).some(l => String(l.id) === String(listId));\n    console.log(stillThere ? 'removal unverified; list still exists' : 'list gone; treat removal as done');\n  } else throw e;\n}","handlingStrategy":"fallback","validationCode":"const lists = await run('twitter', 'lists', { limit: 200 });\nconst target = lists.find(l => String(l.id) === String(listId));\nif (!target) throw new Error(`List ${listId} not visible via lists API — cannot verify removal.`);","typeGuard":"const found = (arr, id) => Array.isArray(arr) && arr.some(l => String(l.id) === String(id));","tryCatchPattern":"try {\n  await listRemoveUser(page, { listId, username });\n} catch (e) {\n  if (String(e.message).includes('missing from post-delete payload')) {\n    // treat as unverified, not failed\n    console.warn(`List ${listId} not in verification page; verify membership separately.`);\n  } else throw e;\n}","preventionTips":["Avoid running this on accounts with more lists than one page returns","Confirm listId matches exactly (numeric string, no whitespace)","Re-run once — pagination order can shift right after mutations","Treat 'unverified' as 'check manually', not 'failed'"],"tags":["verification-failed","pagination","twitter-api"],"backgroundTag":"verification-ambiguous","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}