jackwener/OpenCLI · error · CommandExecutionError

Failed to delete list ${listId}: list still appears in manag

Error message

Failed to delete list ${listId}: list still appears in managed lists.

What it means

After the in-page delete click-through reports success, list-delete re-fetches your managed lists via the ListsManagementPageTimeline GraphQL call and asserts the list is gone. If the listId is still present in that post-delete listing, it throws this CommandExecutionError — the UI flow looked successful but the deletion was not actually effective (or the cache/read lagged).

Source

Thrown at clis/twitter/list-delete.js:153

            if (!editDialog) return { ok: false, message: 'Edit List dialog did not open' };
            const deleteButton = findButton('Delete List');
            if (!deleteButton) return { ok: false, message: 'Delete List button not found' };
            deleteButton.click();
            await sleep(800);
            const confirmButton = document.querySelector('[data-testid="confirmationSheetConfirm"]')
                || findButton('Delete');
            if (!confirmButton) return { ok: false, message: 'Delete confirmation button not found' };
            confirmButton.click();
            await sleep(2500);
            return { ok: true, url: location.href };
        })()`));
        if (!deleteResult?.ok) {
            throw new CommandExecutionError(`Failed to delete list ${listId}: ${deleteResult?.message || 'unknown UI failure'}`);
        }

        const listsAfter = await getManagedLists(page, headers);
        if (listsAfter.some((list) => list.id === listId)) {
            throw new CommandExecutionError(`Failed to delete list ${listId}: list still appears in managed lists.`);
        }

        return [buildListDeleteRow({ listId, targetList })];
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Wait 30–60 seconds and re-run `opencli twitter lists` to confirm whether the list actually still exists before retrying
  2. Re-run the delete command — a first attempt may have silently dismissed the confirmation sheet; the retry usually verifies gone
  3. Open https://x.com/i/lists/<listId> in a browser: if it 404s, the list is deleted and this was a stale-read false positive
  4. Verify you own the list (owner-only deletes take effect; subscriptions can't be deleted this way)
  5. If it consistently persists, delete it manually in the UI and inspect whether the confirm button selector is clicking the wrong element

Example fix

// before (immediate post-delete verification)
const listsAfter = await getManagedLists(page, headers);
// after (allow cache lag before verification)
await sleep(5000);
const listsAfter = await getManagedLists(page, headers);
Defensive patterns

Strategy: retry

Validate before calling

// Post-failure existence check before treating it as a hard failure:
const stillThere = (await run('opencli twitter lists')).some(r => r.listId === listId);
if (!stillThere) console.log('List actually deleted; stale-read false positive');

Type guard

function listIsReallyGone(lists, listId) {
  return Array.isArray(lists) && !lists.some(l => String(l.id) === String(listId));
}

Try / catch

const MAX_ATTEMPTS = 2;
for (let i = 1; i <= MAX_ATTEMPTS; i++) {
  try {
    await run(`opencli twitter list-delete ${listId} --confirm true`);
    break;
  } catch (e) {
    const stillThere = (await run('opencli twitter lists')).some(r => r.listId === listId);
    if (!stillThere) break;                 // verification lag, list is gone
    if (i === MAX_ATTEMPTS) throw e;         // genuine persistence
    await new Promise(r => setTimeout(r, 30000)); // let X.com caches settle
  }
}

Prevention

When it happens

Trigger: deleteResult.ok was true (confirm button clicked, 2.5s slept), but getManagedLists() still returns an entry with the same id. Causes: the confirmation click actually cancelled/dismissed the sheet, the server rejected the delete while the UI optimistically navigated away, X rendered a stale managed-lists timeline, or the deleted list was a follower/subscribed list that re-appears in the management fetch.

Common situations: X.com eventual consistency — the ListsManagementPageTimeline endpoint serves a cached timeline immediately after delete; clicking 'Delete' on a list you don't own (subscriber view still shows delete-looking controls in some layouts); the wrong confirmation button was clicked closing the dialog without deleting.

Related errors


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