{"record":{"id":"871fe67c6641f473","repo":"jackwener/OpenCLI","slug":"result-message-check-muted-words-before-retryin","errorCode":null,"errorMessage":"${result.message} Check muted words before retrying; the word may already have been added.","messagePattern":"(.+?) Check muted words before retrying; the word may already have been added\\.","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"warning","filePath":"clis/twitter/mute-word.js","lineNumber":169,"sourceCode":"                    await sleep(250);\n                    if (beforePath !== '/settings/muted_keywords' && location.pathname === '/settings/muted_keywords') {\n                        return { ok: true, message: 'Muted word added.' };\n                    }\n                    if (hasNewSuccessToast(beforeToasts)) {\n                        return { ok: true, message: 'Muted word added.' };\n                    }\n                    if (hasNewExactKeywordRow(beforeRows)) {\n                        return { ok: true, message: 'Muted word added.' };\n                    }\n                }\n                return { ok: false, unconfirmed: true, message: 'Muted word submission did not show confirmation.' };\n            } catch (error) {\n                return { ok: false, unconfirmed: writeStarted, message: String(error?.message || error) };\n            }\n        })()`);\n\n        if (result?.unconfirmed) {\n            throw new TimeoutError(\n                'twitter mute-word confirmation',\n                5,\n                `${result.message} Check muted words before retrying; the word may already have been added.`,\n            );\n        }\n        if (!result?.ok) {\n            throw new CommandExecutionError(\n                result?.message || 'Could not add muted word.',\n                'Nothing changed. Open Twitter/X muted word settings in the browser and retry.',\n            );\n        }\n\n        return [{\n            keyword,\n            status: 'success',\n            message: result.message || 'Muted word added.',\n        }];\n    },","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/mute-word.js#L151-L187","documentation":"TimeoutError('twitter mute-word confirmation', 5, ...) thrown when the in-page script attempted to add the muted keyword but could not confirm success within the 5-attempt/timeout budget, AND writeStarted is true — meaning the write may have partially gone through. The extra message tells the user to check existing muted words first because a duplicate add is a common cause of the confirmation never appearing.","triggerScenarios":"page.evaluate in-page script returned { ok: false, unconfirmed: true, message } — e.g. the 'Add' button was clicked (writeStarted) but the success toast/row for the new keyword never rendered within the confirmation window, often because the keyword was already muted or the settings page rendered slowly.","commonSituations":"Re-running the command for a keyword that was already muted in a previous (possibly timed-out) run; slow X.com renders on poor connections; Twitter UI changes moving the confirmation element; flaky network causing the toast to be missed.","solutions":["Open https://x.com/settings/muted_keywords and check whether the keyword is already muted; if it is, the operation effectively succeeded — do not retry.","Re-run the command once; if it was a transient slow render it should confirm the second time (watch for a duplicate).","Remove the existing muted keyword first if you need a clean re-add, then run the command again.","If persistent, increase the confirmation timeout or verify the confirmation selector still matches the current X UI, and report a selector drift bug."],"exampleFix":"// before\nawait addMutedKeyword(keyword); // retry blindly on timeout -> duplicates\n// after\nconst muted = await listMutedKeywords();\nif (muted.includes(keyword)) {\n  console.log(`${keyword} already muted; skipping add`);\n} else {\n  await addMutedKeyword(keyword);\n}","handlingStrategy":"retry","validationCode":"const existing = await listMutedKeywords();\nif (existing.includes(keyword)) {\n  console.log(`${keyword} already muted; skipping`);\n  return;\n}","typeGuard":"function isUnconfirmedTimeout(err) {\n  return err instanceof TimeoutError && err.message.includes('Check muted words before retrying');\n}","tryCatchPattern":"try {\n  await run(['twitter', 'mute-word', kw]);\n} catch (err) {\n  if (isUnconfirmedTimeout(err)) {\n    const muted = await listMutedKeywords();\n    if (muted.includes(kw)) console.log(`${kw} was muted despite timeout`);\n    else throw err;\n  } else throw err;\n}","preventionTips":["Check existing muted keywords before adding to avoid ambiguous duplicate timeouts","Retry at most once and verify by listing muted words afterwards","Run on a stable connection so the confirmation toast renders within the window"],"tags":["timeout","twitter","browser-automation","idempotency"],"backgroundTag":"operation-timeout-unconfirmed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}