jackwener/OpenCLI · warning · ArgumentError
Refusing to delete list without --confirm true
Error message
Refusing to delete list without --confirm true
What it means
Deleting a list is destructive and irreversible, so list-delete refuses to run unless the user explicitly passes --confirm true (validated via normalizeConfirm). This is a deliberate safety guard against accidental deletions.
Source
Thrown at clis/twitter/list-delete.js:91
name: 'list-delete',
access: 'write',
description: 'Delete a Twitter/X list you own after explicit confirmation',
domain: 'x.com',
strategy: Strategy.UI,
browser: true,
args: [
{ name: 'listId', positional: true, type: 'string', required: true, help: 'Numeric ID of the list you own (e.g. from `opencli twitter lists`)' },
{ name: 'confirm', type: 'boolean', default: false, help: 'Required. Set --confirm true to delete the list.' },
{ name: 'timeout', type: 'int', default: 300, help: 'Max seconds for the overall delete command (default: 300)' },
],
columns: ['listId', 'name', 'members', 'status', 'message'],
func: async (page, kwargs) => {
const listId = String(kwargs.listId || '').trim();
if (!listId || !/^\d+$/.test(listId)) {
throw new ArgumentError(`Invalid listId: ${JSON.stringify(kwargs.listId)}. Expected numeric ID.`, 'Example: opencli twitter list-delete 123456789 --confirm true');
}
if (!normalizeConfirm(kwargs.confirm)) {
throw new ArgumentError('Refusing to delete list without --confirm true', 'Example: opencli twitter list-delete 123456789 --confirm true');
}
await page.goto('https://x.com');
await page.wait(3);
const cookies = await page.getCookies({ url: 'https://x.com' });
const ct0 = cookies.find((c) => c.name === 'ct0')?.value || null;
if (!ct0) throw new AuthRequiredError('x.com', 'Not logged into x.com (no ct0 cookie)');
const headers = JSON.stringify({
'Authorization': `Bearer ${decodeURIComponent(TWITTER_BEARER_TOKEN)}`,
'X-Csrf-Token': ct0,
'X-Twitter-Auth-Type': 'OAuth2Session',
'X-Twitter-Active-User': 'yes',
});
const listsBefore = await getManagedLists(page, headers);
const targetList = listsBefore.find((list) => list.id === listId);
if (!targetList) {View on GitHub (pinned to 49907e53dc)
Solutions
- Re-run with `--confirm true`
- Check normalizeConfirm's accepted truthy spellings and pass an exact match
- Update automation scripts to include the confirm flag
Example fix
// before opencli twitter list-delete 123456789 // after opencli twitter list-delete 123456789 --confirm true
Defensive patterns
Strategy: validation
Validate before calling
if (!/^(true|True)$/i.test(String(confirmArg))) throw new Error('list-delete requires --confirm true'); Type guard
function isConfirmed(v) {
return v === true || v === 'true';
} Try / catch
try {
await page.func({ listId, confirm: 'true' });
} catch (e) {
if (/Refusing to delete/.test(e.message)) {
console.error('Destructive op requires explicit --confirm true');
} else throw e;
} Prevention
- Always pass --confirm true in scripts that delete
- Use exact lowercase 'true' regardless of casing assumptions
- Gate destructive commands behind a double-check in automation
When it happens
Trigger: `twitter list-delete <id>` invoked without --confirm, with --confirm false, or with a value normalizeConfirm doesn't treat as true (e.g. 'yes', '1', 'y' if unsupported).
Common situations: Running the command interactively and forgetting the flag; scripts written before the confirm requirement existed; automation passing confirm:"True" in a casing/format the normalizer rejects.
Related errors
- ${commandName} requires --execute to perform a remote write
- Refusing to post: pass --execute to actually publish this co
- Refusing to delete pin ${row.pinId}${row.title ? ` "${row.ti
- Refusing to write a local Pixiv novel: pass --execute
- Not a git repository
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/e05f06b8e5bfdb3a.
Report an issue: GitHub.