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

  1. 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.
  2. Re-run `opencli twitter unlike <url>` after verifying state; the command is idempotent (it reports 'already unliked' if the like button is present).
  3. If it happens consistently, check for X.com DOM changes affecting `[data-testid="like"]`/`[data-testid="unlike"]` and update the selectors.
  4. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/9fb9a97d0d86fd6c. Report an issue: GitHub.