jackwener/OpenCLI · error · CommandExecutionError

Nothing changed. Open the tweet in the browser and retry.

Error message

Nothing changed. Open the tweet in the browser and retry.

What it means

CommandExecutionError (code COMMAND_EXEC) from `twitter unbookmark` when the in-page script finished with ok:false and no pending write (unconfirmed=false): the bookmark removal definitively did not happen. The message carries the page script's error text and the hint confirms 'Nothing changed,' so retrying is safe. This is the clean-failure branch, unlike the timeout case.

Source

Thrown at clis/twitter/unbookmark.js:70

            await new Promise(r => setTimeout(r, 1000));

            // Verify
            const verifyArticle = findTargetArticle() || targetArticle;
            const verify = verifyArticle?.querySelector('[data-testid="bookmark"]');
            if (verify) {
                return { ok: true, message: 'Tweet successfully removed from bookmarks.' };
            } else {
                return { ok: false, unconfirmed: true, message: 'Unbookmark action initiated but UI did not update.' };
            }
        } catch (e) {
            return { ok: false, unconfirmed: writeStarted, message: e.toString() };
        }
    })()`);
        if (result.unconfirmed) {
            throw new TimeoutError('twitter unbookmark 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. Inspect the underlying result.message in the error output to identify the failed in-page step
  2. Open the tweet URL in the browser to confirm it loads and you are logged in, then retry
  3. Verify the tweet still exists and is bookmarked (a removed bookmark or deleted tweet has no control to click)
  4. If selectors fail consistently, suspect an X markup change — update or report the library
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: parse the tweet URL and confirm the tweet page loads
const target = parseTweetUrl(url);
await page.goto(target.url);
await page.waitForSelector('[data-testid="primaryColumn"]', { timeout: 10000 });

Type guard

function isCommandExecError(e) { return e && e.code === 'COMMAND_EXEC'; }

Try / catch

try {
  await cli.run(['twitter', 'unbookmark', tweetUrl]);
} catch (e) {
  if (e.code === 'COMMAND_EXEC' && /Nothing changed/.test(e.hint || '')) {
    // clean failure, safe to retry after fixing the cause
    console.error(`Unbookmark failed cleanly: ${e.message}`);
  } else throw e;
}

Prevention

When it happens

Trigger: The evaluate()'d unbookmark script threw before clicking (writeStarted=false) — e.g. tweet URL parsed but the bookmark control was absent or selectors failed — returning {ok:false, unconfirmed:false}, so CommandExecutionError is thrown with the script's message.

Common situations: Tweet deleted or unavailable (removed/protected account) so the bookmark control never renders; X markup change breaking the bookmark button selector; logged-out session showing a different layout; malformed tweet URL landing on the wrong page state.

Related errors


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