jackwener/OpenCLI · warning · TimeoutError
twitter unlike confirmation
Error message
twitter unlike confirmation
What it means
After clicking Unlike inside the page, the in-page script returns `unconfirmed: true` when the write was initiated but the UI never verified success (the 'like' button did not reappear within the verification window, or an in-page exception fired after the click). The CLI maps that to a TimeoutError named 'twitter unlike confirmation' with a 1-unit timeout. This is deliberately treated as ambiguous: the unlike may have actually succeeded on x.com even though the UI did not reflect it.
Source
Thrown at clis/twitter/unlike.js:74
// Click Unlike
writeStarted = true;
unlikeBtn.click();
await new Promise(r => setTimeout(r, 1000));
// Verify success by checking if the 'like' button reappeared
const verifyArticle = findTargetArticle() || targetArticle;
const verifyBtn = verifyArticle?.querySelector('[data-testid="like"]');
if (verifyBtn) {
return { ok: true, message: 'Tweet successfully unliked.' };
} else {
return { ok: false, unconfirmed: true, message: 'Unlike action was initiated but UI did not update as expected.' };
}
} catch (e) {
return { ok: false, unconfirmed: writeStarted, message: e.toString() };
}
})()`);
if (result.unconfirmed) {
throw new TimeoutError('twitter unlike confirmation', 1, `${result.message} Check the tweet before retrying; the unlike may already have succeeded.`);
}
if (!result.ok) {
throw new CommandExecutionError(result.message, 'Nothing changed. Open the tweet in the browser and retry.');
}
await page.wait(2);
return [{
status: 'success',
message: result.message
}];
}
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Do NOT immediately retry blindly — open the tweet in the browser and manually verify whether the like is already gone; retry only if it is still liked.
- Re-run `opencli twitter unlike <url>` after verifying state; the command is idempotent (it reports 'already unliked' if the like button is present).
- If it happens consistently, check for X.com DOM changes affecting `[data-testid="like"]`/`[data-testid="unlike"]` and update the selectors.
- Increase network stability / retry after a short wait if the UI was merely slow to update.
Example fix
// before
opencli twitter unlike $URL && opencli twitter unlike $URL # blind retry can double-click state
// after
opencli twitter unlike $URL || { opencli browser open $URL; } # verify in browser, then retry once Defensive patterns
Strategy: try-catch
Validate before calling
// confirm state before retrying: is the tweet still liked?
const stillLiked = await page.evaluate(`!!document.querySelector('[data-testid="like"]')`);
if (!stillLiked) console.log('Already unliked; skip retry'); Type guard
function isUnconfirmedTimeout(e) {
return e instanceof TimeoutError && e.name === 'twitter unlike confirmation';
} Try / catch
try {
await cli.run(['twitter', 'unlike', tweetUrl]);
} catch (e) {
if (isUnconfirmedTimeout(e)) {
// verify in browser before retrying; the unlike may already have succeeded
const confirmed = await manuallyVerifyUnliked(tweetUrl);
if (confirmed) return;
await retryWithBackoff(() => cli.run(['twitter', 'unlike', tweetUrl]), 1);
} else throw e;
} Prevention
- Never blind-retry after a confirmation timeout — check the tweet state first.
- Ensure a stable network connection so UI updates render within the ~1s verification window.
- Keep selectors/testids in sync if you fork or patch the command.
- Treat this error as ambiguous state and make retries idempotent.
When it happens
Trigger: Clicking the Unlike button succeeded but the follow-up DOM check for `[data-testid="like"]` did not pass within ~1s; an exception thrown inside the page script after `writeStarted = true` (line 57-58 of unlike.js) also sets `unconfirmed: true`.
Common situations: Slow X.com rendering or network lag so the optimistic UI update is delayed; tweet deleted or conversation view changed mid-operation; X.com A/B DOM changes moving the verification selector; rate-limiting or an error toast replacing the article content.
Related errors
- twitter unretweet confirmation
- Unexpected 12306 probe: ${JSON.stringify(probe)}
- Kimi history rename was not verified for chat ${id}
- twitter follow confirmation
- twitter followers API capture
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/9fb9a97d0d86fd6c.
Report an issue: GitHub.