FujiwaraChoki/MoneyPrinterV2 · error · RuntimeError

Could not find the Post button on X compose screen.

Error message

Could not find the Post button on X compose screen.

What it means

RuntimeError raised in Twitter.post when none of the post_button_selectors could be found/clicked, leaving post_button None after the swallow-and-continue loop. The tweet text was entered but the compose screen's Post button never became clickable.

Source

Thrown at src/classes/Twitter.py:132


        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:
                continue

        if post_button is None:
            raise RuntimeError("Could not find the Post button on X compose screen.")

        if verbose:
            print(colored(" => Pressed [ENTER] Button on Twitter..", "blue"))
        time.sleep(2)

        # Add the post to the cache
        self.add_post({"content": body, "date": now.strftime("%m/%d/%Y, %H:%M:%S")})

        success("Posted to Twitter successfully!")

    def get_posts(self) -> List[dict]:
        """
        Gets the posts from the cache.

        Returns:
            posts (List[dict]): The posts
        """
        if not os.path.exists(get_twitter_cache_path()):

View on GitHub (pinned to 5192af8eca)

Solutions

  1. Inspect the live compose DOM and update post_button_selectors with the current button selector (e.g. button[data-testid='tweetButton'])
  2. Wait for button to be enabled (check aria-disabled/disabled attr) before clicking
  3. Dismiss overlay modals or use JS click as fallback
  4. Add WebDriverWait-based clickable condition with a longer timeout

Example fix

# before
for sel in post_button_selectors:
    try:
        post_button.click()
        break
    except Exception:
        continue
# after
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
btn = WebDriverWait(driver, 30).until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-testid='tweetButton']:not([disabled])"))
)
btn.click()
Defensive patterns

Strategy: try-catch

Validate before calling

from selenium.webdriver.common.by import By
btns = driver.find_elements(By.CSS_SELECTOR, "button[data-testid='tweetButton']")
assert btns and btns[0].is_enabled(), "Post button not ready"

Try / catch

try:
    twitter.post(body)
except RuntimeError as e:
    if "Post button" in str(e):
        driver.refresh(); twitter.post(body)  # one retry

Prevention

When it happens

Trigger: Calling post() where the Post button is disabled (empty/rate-limited compose), the button's data-testid changed, an overlay/modal intercepts clicks, or the loop times out before the button renders.

Common situations: X UI updates renaming the button selector, headless rendering differences, slow load after typing, or a draft-state modal blocking the button.

Related errors


AI-assisted analysis of FujiwaraChoki/MoneyPrinterV2@5192af8eca (2026-08-28). Data as JSON: /api/errors/bae4e690e8b34d4e. Report an issue: GitHub.