{"record":{"id":"a50aa9f090b9619d","repo":"jackwener/OpenCLI","slug":"requires-up-to-date-chrome-extension-nativeclick","errorCode":null,"errorMessage":"Requires up-to-date Chrome extension (nativeClick).","messagePattern":"Requires up-to-date Chrome extension \\(nativeClick\\)\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/twitter/list-remove-core.js","lineNumber":227,"sourceCode":"                    rowClickX: Math.round(rowRect.left + rowRect.width / 2),\n                    rowClickY: Math.round(rowRect.top + rowRect.height / 2),\n                    saveClickX: saveRect ? Math.round(saveRect.left + saveRect.width / 2) : null,\n                    saveClickY: saveRect ? Math.round(saveRect.top + saveRect.height / 2) : null,\n                    mutationsBefore: window.__opencliListMutations.length,\n                };\n            } catch (e) {\n                return { ok: false, message: 'UI error: ' + (e?.message || String(e)) };\n            }\n        })()`));\n\n        if (!uiResult.ok) {\n            throw new CommandExecutionError(`Failed to remove @${username} from list ${listId}: ${uiResult.message}`);\n        }\n\n        let verifiedBy = null;\n        if (uiResult.needsNativeInteraction) {\n            if (typeof page.nativeClick !== 'function') {\n                throw new CommandExecutionError('Requires up-to-date Chrome extension (nativeClick).');\n            }\n            if (!uiResult.saveClickX) {\n                throw new CommandExecutionError('Save button not found in dialog.');\n            }\n            const memberCountBefore = Number(targetList.members) || 0;\n            await page.nativeClick(uiResult.rowClickX, uiResult.rowClickY);\n            await new Promise((r) => setTimeout(r, 800));\n            await page.nativeClick(uiResult.saveClickX, uiResult.saveClickY);\n            await new Promise((r) => setTimeout(r, 3500));\n            const listsAfter = unwrapBrowserResult(await page.evaluate(`async () => {\n                const r = await fetch(${JSON.stringify(listsUrl)}, { headers: ${headers}, credentials: 'include' });\n                if (!r.ok) return { __error: 'HTTP ' + r.status };\n                return await r.json();\n            }`));\n            if (listsAfter && listsAfter.__error) {\n                throw new CommandExecutionError(`Could not verify list removal: ${listsAfter.__error}`);\n            }\n            if (!getListsManagementInstructions(listsAfter)) {","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/list-remove-core.js#L209-L245","documentation":"When the in-page UI flow cannot finish by itself it reports needsNativeInteraction, expecting the host browser page object to expose nativeClick for trusted, OS-level clicks (e.g. on x.com's save/confirm button). If page.nativeClick is not a function, the environment's Chrome extension/bridge is too old, and this CommandExecutionError is thrown. The operation cannot be completed without upgrading.","triggerScenarios":"Running listRemoveUser against a browser adapter that lacks nativeClick — an outdated Chrome extension, a generic Puppeteer/Playwright page object instead of the opencli browser strategy, or an extension that was not reloaded after an update.","commonSituations":"User pinned an old version of the companion Chrome extension; extension updated in the store but the browser was not restarted/reloaded; using the library with a plain automation driver that never implemented nativeClick; mismatched versions of the CLI and the browser extension.","solutions":["Update the companion Chrome extension to the latest version and reload the browser (chrome://extensions → reload, or restart the browser).","Verify the page object passed to listRemoveUser comes from the opencli browser strategy (which implements nativeClick), not a raw Puppeteer/Playwright page.","Confirm extension and CLI versions match — reinstall both if the bridge still reports no nativeClick.","As a workaround, perform the final save/confirm click manually in the visible browser window while the command waits."],"exampleFix":"// before (raw puppeteer page lacks nativeClick)\nawait listRemoveUser(await browser.newPage(), { listId, username });\n// after\nconst page = await opencliBrowser.newPage(); // strategy page with nativeClick bridge\nawait listRemoveUser(page, { listId, username });","handlingStrategy":"validation","validationCode":"// Feature-detect the native bridge before running the command\nif (typeof page.nativeClick !== 'function') {\n  throw new Error('Update the companion Chrome extension (or use an opencli strategy page that implements nativeClick).');\n}\nawait listRemoveUser(page, { listId, username });","typeGuard":"function supportsNativeClick(page) {\n  return page !== null && typeof page === 'object' && typeof page.nativeClick === 'function';\n}","tryCatchPattern":"try {\n  await listRemoveUser(page, { listId, username });\n} catch (e) {\n  if (e instanceof CommandExecutionError && e.message.includes('nativeClick')) {\n    throw new Error('Upgrade the Chrome extension and reload the browser, then retry.');\n  } else throw e;\n}","preventionTips":["Keep the companion Chrome extension on its latest version.","Reload or restart the browser after extension updates.","Only pass opencli strategy pages (not raw Puppeteer/Playwright pages) to commands needing native interaction.","Feature-detect page.nativeClick at startup and fail fast with a clear message."],"tags":["chrome-extension","browser-automation","version-mismatch","native-click"],"backgroundTag":"extension-version-outdated","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}