Skip to content

fix(twitter): drop global tweetPhoto from hasMedia in post submit poll#1812

Open
Benjamin-eecs wants to merge 1 commit into
jackwener:mainfrom
Benjamin-eecs:fix/twitter-post-images-false-timeout
Open

fix(twitter): drop global tweetPhoto from hasMedia in post submit poll#1812
Benjamin-eecs wants to merge 1 commit into
jackwener:mainfrom
Benjamin-eecs:fix/twitter-post-images-false-timeout

Conversation

@Benjamin-eecs
Copy link
Copy Markdown
Contributor

@Benjamin-eecs Benjamin-eecs commented Jun 1, 2026

Description

submitTweet in clis/twitter/post.js polls after clicking the tweet button. The success path falls through to !composerStillHasText && !hasMedia once the composer clears, but hasMedia was queried against the entire document: document.querySelector('[data-testid="attachments"], [data-testid="tweetPhoto"]'). tweetPhoto is rendered for every tweet's image in the timeline, including the tweet that was just posted, so hasMedia pinned true past the success path and the poll ran until Tweet submission did not complete before timeout., even though the tweet is live on the user's timeline.

Drop tweetPhoto from the query. attachments (the composer's attachment container) and img[src^="blob:"] / video[src^="blob:"] (the local preview URLs created by the composer's image picker) are composer-only signals and clear when the composer dismisses.

Related issue: fixes #1781.

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 🌐 New site adapter
  • 📝 Documentation
  • ♻️ Refactor
  • 🔧 CI / build / tooling

Checklist

  • I ran the checks relevant to this PR
  • I updated tests or docs if needed
  • I included output or screenshots when useful

Screenshots / Output

Live verified on a logged-in twitter session on macOS 26.5 with opencli 1.8.1 + Browser Bridge v1.0.15. To force the buggy code path I temporarily replaced the toast-detection regex with one that never matches (so the success-toast short-circuit was disabled and the poll fell through to the !composerStillHasText && !hasMedia check):

post.js variant toast regex Result
main (canonical 1.8.1) disabled (/__NEVER_MATCH/) status: failed, Tweet submission did not complete before timeout. after 19s, tweet IS live on timeline (reporter's exact symptom)
patched disabled (/__NEVER_MATCH/) status: success, returns URL, 5.8s
patched unchanged status: success via toast path (no regression on the happy path)

All four test tweets were deleted from the account after the run. Full twitter suite continues to pass: 391/391.

tweetPhoto exists for every timeline tweet image so the global query pinned hasMedia true past the success path; attachments + blob: URLs are composer-only.

Fixes jackwener#1781
@Benjamin-eecs Benjamin-eecs force-pushed the fix/twitter-post-images-false-timeout branch from 342f553 to 71a664e Compare June 1, 2026 07:25
@Benjamin-eecs Benjamin-eecs changed the title fix(twitter): scope hasMedia to composer ancestor in post submit poll fix(twitter): drop global tweetPhoto from hasMedia in post submit poll Jun 1, 2026
@Benjamin-eecs Benjamin-eecs marked this pull request as ready for review June 1, 2026 07:28
Copilot AI review requested due to automatic review settings June 1, 2026 07:28
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adjusts tweet composer media detection to prevent false positives when determining whether a tweet has been successfully posted.

Changes:

  • Stops using the global [data-testid="tweetPhoto"] selector, which can match timeline content and keep hasMedia true after posting.
  • Adds clarification comments on why media detection should be composer-scoped.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread clis/twitter/post.js
Comment on lines 236 to 242
const boxes = Array.from(document.querySelectorAll('[data-testid="tweetTextarea_0"]')).filter(visible);
const composerStillHasText = boxes.some((box) => normalize(box.innerText || box.textContent || '').includes(expectedText));
const hasMedia = !!document.querySelector('[data-testid="attachments"], [data-testid="tweetPhoto"]')
// Drop the global tweetPhoto query: tweetPhoto exists for every
// timeline tweet's image and would pin hasMedia true past the
// success path. attachments + blob: URLs are composer-only.
const hasMedia = !!document.querySelector('[data-testid="attachments"]')
|| document.querySelectorAll('img[src^="blob:"], video[src^="blob:"]').length > 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

twitter post --images reports timeout failure but tweet is actually posted successfully

2 participants