FujiwaraChoki/MoneyPrinterV2 · error · RuntimeError
Could not find tweet text box. Ensure you are logged into X
Error message
Could not find tweet text box. Ensure you are logged into X in this Firefox profile.
What it means
RuntimeError raised in Twitter.post after the selector loop failed to locate the tweet compose text box in any iteration (each Exception swallowed by `continue`, leaving text_box None). It almost always means the page never reached a logged-in compose state in this Firefox profile.
Source
Thrown at src/classes/Twitter.py:111
text_box = None
text_box_selectors = [
(By.CSS_SELECTOR, "div[data-testid='tweetTextarea_0'][role='textbox']"),
(By.XPATH, "//div[@data-testid='tweetTextarea_0']//div[@role='textbox']"),
(By.XPATH, "//div[@role='textbox']"),
]
for selector in text_box_selectors:
try:
text_box = self.wait.until(EC.element_to_be_clickable(selector))
text_box.click()
text_box.send_keys(body)
break
except Exception:
continue
if text_box is None:
raise RuntimeError(
"Could not find tweet text box. Ensure you are logged into X in this Firefox profile."
)
post_button = None
post_button_selectors = [
(By.XPATH, "//button[@data-testid='tweetButtonInline']"),
(By.XPATH, "//button[@data-testid='tweetButton']"),
(By.XPATH, "//span[text()='Post']/ancestor::button"),
]
for selector in post_button_selectors:
try:
post_button = self.wait.until(EC.element_to_be_clickable(selector))
post_button.click()
break
except Exception:
continueView on GitHub (pinned to 5192af8eca)
Solutions
- Open Firefox with the same profile non-headless and confirm you are logged into X
- Re-run login flow / restore session cookies in the profile
- Update text_box_selectors to match current X compose DOM (inspect with devtools)
- Increase wait/timeout or use WebDriverWait with expected_conditions instead of a fixed loop
Example fix
# before
for sel in text_box_selectors:
try:
text_box = driver.find_element(By.CSS_SELECTOR, sel)
text_box.send_keys(body)
break
except Exception:
continue
# after
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
box = WebDriverWait(driver, 30).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "div[data-testid='tweetTextarea_0']"))
)
box.send_keys(body) Defensive patterns
Strategy: try-catch
Validate before calling
from selenium.webdriver.common.by import By found = driver.find_elements(By.CSS_SELECTOR, "div[data-testid='tweetTextarea_0']") assert found, "compose box absent — check login state"
Try / catch
try:
twitter.post(body)
except RuntimeError as e:
if "tweet text box" in str(e):
# re-login or refresh profile session, then retry once
... Prevention
- Keep the Firefox profile logged in; verify session before batch runs
- Use WebDriverWait + expected_conditions instead of swallow-all loops
- Pin selectors via data-testid and review them after X UI updates
When it happens
Trigger: Calling post() when the X/Twitter session in the Firefox profile is logged out, the compose URL/DOM changed so all text_box_selectors miss, or the page had not finished loading within the wait loop.
Common situations: Expired X session cookie in the profile, X A/B-tested new compose markup, slow network causing timeout before the box renders, or headless mode being detected.
Related errors
- Could not find the Post button on X compose screen.
- Firefox profile path does not exist or is not a directory: {
- Firefox profile path does not exist or is not a directory: {
- Firefox profile path does not exist or is not a directory: {
AI-assisted analysis of FujiwaraChoki/MoneyPrinterV2@5192af8eca (2026-08-28).
Data as JSON: /api/errors/32d734b9519f9d4d.
Report an issue: GitHub.