{"record":{"id":"72bce96a0caa37e5","repo":"jackwener/OpenCLI","slug":"browser-session-required-for-twitter-block","errorCode":null,"errorMessage":"Browser session required for twitter block","messagePattern":"Browser session required for twitter block","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/twitter/block.js","lineNumber":17,"sourceCode":"import { CommandExecutionError, TimeoutError } from '@jackwener/opencli/errors';\nimport { cli, Strategy } from '@jackwener/opencli/registry';\ncli({\n    site: 'twitter',\n    name: 'block',\n    access: 'write',\n    description: 'Block a Twitter user',\n    domain: 'x.com',\n    strategy: Strategy.UI,\n    browser: true,\n    args: [\n        { name: 'username', type: 'string', positional: true, required: true, help: 'Twitter screen name (without @)' },\n    ],\n    columns: ['status', 'message'],\n    func: async (page, kwargs) => {\n        if (!page)\n            throw new CommandExecutionError('Browser session required for twitter block');\n        const username = kwargs.username.replace(/^@/, '');\n        await page.goto(`https://x.com/${username}`);\n        await page.wait({ selector: '[data-testid=\"primaryColumn\"]' });\n        const result = await page.evaluate(`(async () => {\n        let writeStarted = false;\n        try {\n            let attempts = 0;\n            const getPrimary = () => document.querySelector('[data-testid=\"primaryColumn\"]');\n            const isBlockMenuItem = (item) => {\n                const text = String(item.textContent || '');\n                const lower = text.toLowerCase();\n                const isUnblockText = lower.includes('unblock') || text.includes('取消屏蔽') || text.includes('解除屏蔽');\n                const isBlockText = (lower.includes('block') || text.includes('屏蔽')) && !isUnblockText;\n                return item.getAttribute('data-testid') === 'block' || isBlockText;\n            };\n            if (!getPrimary()) {\n                return { ok: false, message: 'Could not find profile surface. Are you logged in?' };\n            }","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/block.js#L1-L35","documentation":"The twitter block command's func requires an interactive browser page; when page is null it throws CommandExecutionError('Browser session required for twitter block'). Blocking is performed by driving the real x.com UI (menus, confirm dialog), so it cannot run without an active browser session.","triggerScenarios":"Invoking the twitter block command in a context where no browser page is bound — e.g. calling the command outside the browser-attached command registry, or the browser session was closed/not started before running the command.","commonSituations":"Running the command before starting the CLI's browser, after closing the browser window, in CI without a browser, or calling the underlying function directly without page injection.","solutions":["Start/open a browser session (the CLI's browser open command) before running twitter block.","Re-run the command through the normal CLI entrypoint so the page is injected into func.","Ensure the browser hasn't crashed/closed mid-session; restart it if needed.","For headless automation, launch the controlled browser (headless is fine) rather than skipping it."],"exampleFix":"// before\nawait cli.run('twitter block @user');\n// after\nawait cli.run('browser open');\nawait cli.run('auth login x.com');\nawait cli.run('twitter block @user');","handlingStrategy":"validation","validationCode":"if (!cli.isBrowserOpen()) {\n  await cli.run('browser open');\n}\nif (!(await hasSessionCookies('x.com'))) {\n  await cli.run('auth login x.com');\n}","typeGuard":"function hasPage(ctx) {\n  return ctx !== null && ctx !== undefined && typeof ctx.page === 'object' && ctx.page !== null;\n}","tryCatchPattern":"try {\n  await cli.run('twitter block @user');\n} catch (e) {\n  if (/Browser session required/.test(e.message)) {\n    await cli.run('browser open');\n    return cli.run('twitter block @user');\n  }\n  throw e;\n}","preventionTips":["Always open the browser session before browser-backed commands","Wrap multi-step flows so the browser lifecycle outlives each command","Detect closed/crashed browsers and restart before retrying","Run these commands only through entrypoints that inject page"],"tags":["browser-session","prerequisite","setup"],"backgroundTag":"missing-browser-session","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}