jackwener/OpenCLI · error · CommandExecutionError

Could not type tweet text.

Error message

Could not type tweet text.

What it means

CommandExecutionError thrown when insertComposerText cannot type/verify the tweet text in the Draft.js composer. The hint tells the user to open the composer in the browser and check whether X is asking them to log in, because the most common cause is a lost session.

Source

Thrown at clis/twitter/post.js:343

                    if (!isRecoverableFileInputError(err)) {
                        throw err;
                    }
                    await attachImagesViaDataTransfer(page, absPaths);
                }
            } else {
                await attachImagesViaDataTransfer(page, absPaths);
            }
            const uploadState = await waitForImageUpload(page, absPaths.length);
            if (!uploadState?.ok) {
                throw new TimeoutError('twitter image upload', UPLOAD_TIMEOUT_MS / 1000, 'Nothing was posted. Retry, or attach a smaller image.');
            }
        }

        // Insert and verify the text after media upload so text + images are in
        // the final Draft.js composer state immediately before clicking Post.
        const typeResult = await insertComposerText(page, text);
        if (!typeResult?.ok) {
            throw new CommandExecutionError(typeResult?.message ?? 'Could not type tweet text.', 'Open the composer in the browser and check whether X is asking you to log in.');
        }

        await page.wait(1);
        const result = await submitTweet(page, text);
        if (result?.unconfirmed) {
            // The poll expiring does not mean the tweet stayed in the composer,
            // so this must not read as a definite failure: the agent workflow
            // retries CommandExecutionError and would post twice (#2255).
            throw new TimeoutError('twitter post', SUBMIT_TIMEOUT_MS / 1000, `${result.message} Check \`opencli twitter tweets --limit 1\` before retrying; the post may already be live.`);
        }
        if (!result?.ok) {
            throw new CommandExecutionError(result?.message ?? 'Tweet failed to post.', 'Nothing was posted. Open the composer in the browser and retry.');
        }
        return [{
            status: 'success',
            message: result.message,
            text,
            ...(result.id ? { id: result.id } : {}),

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open the browser session and confirm you are logged into X (the error's own suggestion); re-authenticate if needed
  2. Retry once — a transient login wall often clears after a fresh page.goto
  3. Check whether X is showing an interstitial (verification, suspension, ToS notice) on the account
  4. If it persists after re-login, the composer DOM may have changed; update or report the insertComposerText selectors
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await postTweet({ text });
} catch (e) {
  if (e.name === 'CommandExecutionError' && /type tweet text/i.test(e.message)) {
    await relogin();            // session likely expired
    return postTweet({ text });
  }
  throw e;
}

Prevention

When it happens

Trigger: insertComposerText(page, text) returns { ok: false } — the textarea never accepts input or the typed text is not reflected in the composer state — typically because X rendered a login wall or the editor selector changed.

Common situations: Expired X session cookies mid-run; X showing an age/account-verification interstitial; rate limiting that soft-blocks posting; the composer DOM changing after an X frontend deploy.

Related errors


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