jackwener/OpenCLI · warning · TimeoutError

twitter unretweet confirmation

Error message

twitter unretweet confirmation

What it means

The unretweet flow clicks Unretweet and then the confirm menu item, setting `writeStarted = true` right before the confirm click. If the subsequent UI verification (the plain 'retweet' button reappearing on the target article) fails, or an in-page exception occurs after the write started, the script returns `unconfirmed: true` and the CLI throws this TimeoutError. The retweet removal is ambiguous — it may or may not have gone through.

Source

Thrown at clis/twitter/unretweet.js:88

            }
            writeStarted = true;
            confirmBtn.click();
            await new Promise(r => setTimeout(r, 1000));

            // Verify success by checking if the 'retweet' button reappeared
            const verifyArticle = findTargetArticle() || targetArticle;
            const verifyBtn = verifyArticle?.querySelector('[data-testid="retweet"]');
            if (verifyBtn) {
                return { ok: true, message: 'Tweet successfully unretweeted.' };
            } else {
                return { ok: false, unconfirmed: true, message: 'Unretweet 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 unretweet confirmation', 1, `${result.message} Check the tweet before retrying; the removal 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. Open the tweet in the browser and check whether the retweet is actually gone before doing anything else.
  2. If still retweeted, re-run `opencli twitter unretweet <url>`; the command is idempotent ('already removed' if the retweet button shows).
  3. If it recurs, check whether X.com changed the retweet/unretweetConfirm data-testids and update them.
  4. Retry after a brief wait if the UI was merely slow to reflect the change.

Example fix

// before
opencli twitter unretweet $URL; opencli twitter unretweet $URL   # blind retry
// after
opencli twitter unretweet $URL || opencli browser open $URL      # verify state, then retry once
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm current retweet state before acting
const retweeted = await page.evaluate(`!!document.querySelector('[data-testid="unretweet"]')`);
if (!retweeted) console.log('Not currently retweeted; nothing to do');

Type guard

function isUnconfirmedTimeout(e) {
  return e instanceof TimeoutError && e.name === 'twitter unretweet confirmation';
}

Try / catch

try {
  await cli.run(['twitter', 'unretweet', tweetUrl]);
} catch (e) {
  if (isUnconfirmedTimeout(e)) {
    const removed = await manuallyVerifyUnretweeted(tweetUrl);
    if (removed) return;
    await retryWithBackoff(() => cli.run(['twitter', 'unretweet', tweetUrl]), 1);
  } else throw e;
}

Prevention

When it happens

Trigger: Confirm click happened but the article still shows no `[data-testid="retweet"]` after ~1s; the unretweetConfirm popover handling raced or an exception fired after `writeStarted = true` (unretweet.js:71-72).

Common situations: Slow x.com updates or network lag after confirm; the confirm menu item (`[data-testid="unretweetConfirm"]`) appearing but the state change lagging; concurrent sessions toggling retweet state; X.com DOM changes breaking the verification selector.

Related errors


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