{"record":{"id":"70cf19281f243649","repo":"jackwener/OpenCLI","slug":"result-message-check-the-profile-before-retryin","errorCode":null,"errorMessage":"${result.message} Check the profile before retrying; the block may already have succeeded.","messagePattern":"(.+?) Check the profile before retrying; the block may already have succeeded\\.","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"clis/twitter/block.js","lineNumber":103,"sourceCode":"                return { ok: false, message: 'Block confirmation dialog did not appear.' };\n            }\n            writeStarted = true;\n            confirmBtn.click();\n            await new Promise(r => setTimeout(r, 1500));\n\n            // Verify\n            const verify = getPrimary()?.querySelector('[data-testid$=\"-unblock\"]');\n            if (verify) {\n                return { ok: true, message: 'Successfully blocked @${username}.' };\n            } else {\n                return { ok: false, unconfirmed: true, message: 'Block action initiated but UI did not update.' };\n            }\n        } catch (e) {\n            return { ok: false, unconfirmed: writeStarted, message: e.toString() };\n        }\n    })()`);\n        if (result.unconfirmed) {\n            throw new TimeoutError('twitter block confirmation', 1.5, `${result.message} Check the profile before retrying; the block may already have succeeded.`);\n        }\n        if (!result.ok) {\n            throw new CommandExecutionError(result.message, 'Nothing changed. Open the profile in the browser and retry.');\n        }\n        await page.wait(2);\n        return [{\n                status: 'success',\n                message: result.message\n            }];\n    }\n});\n","sourceCodeStart":85,"sourceCodeEnd":115,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/block.js#L85-L115","documentation":"When the in-page block script reports ok:false without unconfirmed=true, the CLI throws CommandExecutionError(result.message, 'Nothing changed. Open the profile in the browser and retry.'). This means the block flow failed before the destructive write began (unlike the unconfirmed TimeoutError case), so no state change happened and the failure is safe to retry after manual inspection.","triggerScenarios":"The page script returned { ok:false, message } from any of its guard branches: profile surface not found, user actions menu missing, Block menu item not found, or the confirmation dialog did not appear — with writeStarted still false.","commonSituations":"Not logged in (profile surface absent), target username doesn't exist or is suspended, Twitter UI variant hides the userActions button, localized UI text not matched by the block-text heuristic, or a slow render so menus never appear within the ~10s polling window.","solutions":["Open the target profile in the controlled browser to confirm it exists and you are logged in.","Re-run the command; transient render delays are the most common cause of missing menus/confirm dialog.","Verify the username (without @) is correct and the account is not suspended/deleted.","Update the CLI if Twitter changed data-testid attributes (userActions, confirmationSheetConfirm) or menu labels."],"exampleFix":"// before\nawait cli.run('twitter block @user');\n// after\ntry {\n  await cli.run('twitter block @user');\n} catch (e) {\n  console.error(e.message, e.hint || ''); // inspect, then retry after checking profile\n  await cli.run('browser open https://x.com/user');\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight: confirm the profile exists and is viewable\nconst res = await page.goto('https://x.com/' + username);\nif (!res || res.status() === 404) throw new Error('Profile ' + username + ' not found');","typeGuard":"function isBlockFailure(result) {\n  return result !== null && typeof result === 'object' && result.ok === false && result.unconfirmed !== true;\n}","tryCatchPattern":"try {\n  await cli.run('twitter block @user');\n} catch (e) {\n  if (/Nothing changed/.test(e.message)) {\n    console.warn('Block not applied:', e.message, e.hint);\n    await verifyProfileManually('user');\n    return cli.run('twitter block @user'); // retry-safe: no write started\n  }\n  throw e;\n}","preventionTips":["Verify the target account exists and is not suspended before blocking","Ensure an active x.com login so profile surfaces and menus render","Retry once — this error is thrown before any write, so it is safe","Update the CLI when Twitter changes data-testid attributes or menu labels"],"tags":["ui-automation","block-action","retry-safe"],"backgroundTag":"ui-automation-step-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}