jackwener / jackwener/OpenCLI

`twitter post` fails — X home page React does not hydrate in automation browser

Open
#2,024 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
29.3k
Forks
2.9k
Avg merge
15h 36m
Merged PRs (30d)
70

Description

## Environment

- OpenCLI: v1.8.4
- OS: macOS (Apple Silicon)
- Browser: Chrome 149 (automation browser via OpenCLI daemon)
- X session: valid (logged in, confirmed by `twitter like` and `twitter reply` working)

## Bug

`opencli twitter post "text"` fails with:

```
Error: Selector not found: [data-testid="tweetTextarea_0"]
```

## Root Cause

X.com home page and `/compose/post` do not fully render in the automation browser. The HTML shell loads but React does not hydrate — **zero `data-testid` elements** exist on the page.

### Debug output (added instrumentation to post.js):

```
url: "https://x.com/home"
reactRootChildren: 2152 (minimal — just the shell)
testIds: [] (empty — React never hydrated)
hasTimeline: false
hasSideNav: false
title: "" (empty — React never set it)
bodyChildren: 21
```

The page is just a static HTML skeleton. No timeline, no compose button, no interactive elements.

### `/compose/post` also fails

Direct navigation to `https://x.com/compose/post` shows a `ScriptLoadFailure` page with the message "Something went wrong, but don't fret — let's give it another shot." and a note about privacy extensions.

## What still works

| Command | Status | Why |
|---------|--------|-----|
| `twitter like` | ✅ | Navigates to a specific tweet URL — React hydrates on tweet pages |
| `twitter reply` | ✅ | Same — operates on an existing tweet page |
| `twitter search` | ✅ | Search results page renders fine |
| `twitter timeline` | ✅ | Home timeline data is fetched via API, not DOM |
| `twitter post` | ❌ | Needs the compose UI on home or /compose/post — both fail to hydrate |

## Suspected cause

X has tightened anti-bot detection specifically on the home page and standalone compose route. Tweet pages (`/user/status/id`) appear to have lighter protection, which is why `like`/`reply`/`search` still work.

The Chrome 149 automation browser may be fingerprinted (navigator.webdriver, CDP detection, etc.) and X blocks React initialization on sensitive routes.

## Possible fixes

1. **Navigate to a tweet first, then use the reply composer as a post composer** — since tweet pages hydrate, open a random tweet, click reply, type, then submit. Hacky but might work.
2. **Use X API (v2) for posting** — bypass the DOM entirely for write operations.
3. **Stealth browser patches** — undetected-chromedriver style patches to avoid bot detection (significant effort).
4. **Post from a bound Chrome tab** — if the user has a real Chrome session logged into X, bind it and post from there (avoids automation browser fingerprinting).

Happy to help test any of these approaches.

Contributor guide

Open the contributing guide

Research direction

Start with post.js and reproduce the `twitter post` command against X home and `/compose/post`, checking the reported hydration diagnostics and selector failure. Compare the behavior with the working tweet, search, and timeline commands; the work is done when an agreed approach makes posting succeed in the listed automation environment.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react
Domain
cli, devtools
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.