{"record":{"id":"15db55a4a5582c95","repo":"jackwener/OpenCLI","slug":"nothing-changed-open-the-tweet-in-the-browser-and-15db55","errorCode":null,"errorMessage":"Nothing changed. Open the tweet in the browser and retry.","messagePattern":"Nothing changed\\. Open the tweet in the browser and retry\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/twitter/unlike.js","lineNumber":77,"sourceCode":"            await new Promise(r => setTimeout(r, 1000));\n\n            // Verify success by checking if the 'like' button reappeared\n            const verifyArticle = findTargetArticle() || targetArticle;\n            const verifyBtn = verifyArticle?.querySelector('[data-testid=\"like\"]');\n            if (verifyBtn) {\n                return { ok: true, message: 'Tweet successfully unliked.' };\n            } else {\n                return { ok: false, unconfirmed: true, message: 'Unlike action was initiated but UI did not update as expected.' };\n            }\n        } catch (e) {\n            return { ok: false, unconfirmed: writeStarted, message: e.toString() };\n        }\n    })()`);\n        if (result.unconfirmed) {\n            throw new TimeoutError('twitter unlike confirmation', 1, `${result.message} Check the tweet before retrying; the unlike may already have succeeded.`);\n        }\n        if (!result.ok) {\n            throw new CommandExecutionError(result.message, 'Nothing changed. Open the tweet 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":59,"sourceCodeEnd":86,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/unlike.js#L59-L86","documentation":"When the in-page unlike script returns `ok: false` (and `unconfirmed` is falsy), the CLI wraps the page's `result.message` in a CommandExecutionError with the remediation hint 'Nothing changed. Open the tweet in the browser and retry.' Unlike the confirmation timeout, this path means the script deterministically failed BEFORE any write was started — the unlike was definitely not applied.","triggerScenarios":"The Unlike button was not found after the 10s poll ('Could not find the Unlike button... Are you logged in?'), typically because the user is logged out or the tweet/article for the given status id never rendered; any other in-page failure captured before `writeStarted = true`.","commonSituations":"Expired or missing x.com login session so the unlike control is absent; wrong/deleted tweet URL; protected tweet or conversation page where the target article is not in the DOM; rate limiting hiding action buttons.","solutions":["Open the tweet URL in the opencli browser, confirm you are logged in and can see the Unlike button, then re-run the command.","Re-authenticate the x.com session (log in again) if the buttons are missing due to a logged-out state.","Verify the tweet URL is valid and the tweet still exists (parseTweetUrl resolved it, but the tweet may be deleted).","If it persists, inspect for X.com DOM/data-testid changes and update selectors."],"exampleFix":"// before\nopencli twitter unlike https://x.com/user/status/123   // fails: logged out, no Unlike button\n// after\nopencli browser login x.com                              # restore session\nopencli twitter unlike https://x.com/user/status/123","handlingStrategy":"validation","validationCode":"// pre-check: logged in and the unlike control is reachable\nconst ready = await page.evaluate(`!!document.querySelector('[data-testid=\"AppTabBar_Profile_Link\"]')`);\nif (!ready) throw new Error('Not logged into x.com; unlike will fail');","typeGuard":"function isDeterministicUnlikeFailure(e) {\n  return e instanceof CommandExecutionError && /Nothing changed/.test(String(e.hint || e.message));\n}","tryCatchPattern":"try {\n  await cli.run(['twitter', 'unlike', tweetUrl]);\n} catch (e) {\n  if (isDeterministicUnlikeFailure(e)) {\n    await ensureXLogin();        // restore session\n    await cli.run(['twitter', 'unlike', tweetUrl]);\n  } else throw e;\n}","preventionTips":["Verify the x.com session is alive before write commands.","Validate the tweet URL resolves to an existing, non-protected tweet.","Watch for X.com data-testid changes after site updates.","Open the tweet in the browser once to confirm the Unlike button is visible before automating."],"tags":["twitter","dom","authentication","ui-automation"],"backgroundTag":"dom-element-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}