{"record":{"id":"e05f06b8e5bfdb3a","repo":"jackwener/OpenCLI","slug":"refusing-to-delete-list-without-confirm-true","errorCode":null,"errorMessage":"Refusing to delete list without --confirm true","messagePattern":"Refusing to delete list without --confirm true","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"warning","filePath":"clis/twitter/list-delete.js","lineNumber":91,"sourceCode":"    name: 'list-delete',\n    access: 'write',\n    description: 'Delete a Twitter/X list you own after explicit confirmation',\n    domain: 'x.com',\n    strategy: Strategy.UI,\n    browser: true,\n    args: [\n        { name: 'listId', positional: true, type: 'string', required: true, help: 'Numeric ID of the list you own (e.g. from `opencli twitter lists`)' },\n        { name: 'confirm', type: 'boolean', default: false, help: 'Required. Set --confirm true to delete the list.' },\n        { name: 'timeout', type: 'int', default: 300, help: 'Max seconds for the overall delete command (default: 300)' },\n    ],\n    columns: ['listId', 'name', 'members', 'status', 'message'],\n    func: async (page, kwargs) => {\n        const listId = String(kwargs.listId || '').trim();\n        if (!listId || !/^\\d+$/.test(listId)) {\n            throw new ArgumentError(`Invalid listId: ${JSON.stringify(kwargs.listId)}. Expected numeric ID.`, 'Example: opencli twitter list-delete 123456789 --confirm true');\n        }\n        if (!normalizeConfirm(kwargs.confirm)) {\n            throw new ArgumentError('Refusing to delete list without --confirm true', 'Example: opencli twitter list-delete 123456789 --confirm true');\n        }\n\n        await page.goto('https://x.com');\n        await page.wait(3);\n        const cookies = await page.getCookies({ url: 'https://x.com' });\n        const ct0 = cookies.find((c) => c.name === 'ct0')?.value || null;\n        if (!ct0) throw new AuthRequiredError('x.com', 'Not logged into x.com (no ct0 cookie)');\n\n        const headers = JSON.stringify({\n            'Authorization': `Bearer ${decodeURIComponent(TWITTER_BEARER_TOKEN)}`,\n            'X-Csrf-Token': ct0,\n            'X-Twitter-Auth-Type': 'OAuth2Session',\n            'X-Twitter-Active-User': 'yes',\n        });\n\n        const listsBefore = await getManagedLists(page, headers);\n        const targetList = listsBefore.find((list) => list.id === listId);\n        if (!targetList) {","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/list-delete.js#L73-L109","documentation":"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.","triggerScenarios":"`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).","commonSituations":"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.","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"],"exampleFix":"// before\nopencli twitter list-delete 123456789\n// after\nopencli twitter list-delete 123456789 --confirm true","handlingStrategy":"validation","validationCode":"if (!/^(true|True)$/i.test(String(confirmArg))) throw new Error('list-delete requires --confirm true');","typeGuard":"function isConfirmed(v) {\n  return v === true || v === 'true';\n}","tryCatchPattern":"try {\n  await page.func({ listId, confirm: 'true' });\n} catch (e) {\n  if (/Refusing to delete/.test(e.message)) {\n    console.error('Destructive op requires explicit --confirm true');\n  } else throw e;\n}","preventionTips":["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"],"tags":["safety-guard","confirmation","cli"],"backgroundTag":"missing-required-flag","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}