moeru-ai/airi · error

Failed to like tweet: ${errorToMessage(error)}

Error message

Failed to like tweet: ${errorToMessage(error)}

What it means

Thrown by likeTweet as the outer catch-all: any error inside the function — 'Like button not found', a click failure, or a waitForFunction timeout (the aria-pressed 'true' assertion did not hold within 5000 ms) — is caught, logged to console.error, and re-thrown as a new Error prefixed 'Failed to like tweet:' with the original message stringified via errorToMessage. The original cause is not attached via .cause.

Source

Thrown at integrations/twitter-services/src/core/services/tweet.ts:139

      const isAlreadyLiked = await page.$eval(
        SELECTORS.TIMELINE.LIKE_BUTTON,
        el => el.getAttribute('aria-pressed') === 'true',
      )

      if (!isAlreadyLiked) {
        await likeButton.click()
        // Wait for the like to register
        await page.waitForFunction(
          `document.querySelector('${SELECTORS.TIMELINE.LIKE_BUTTON}')?.getAttribute('aria-pressed') === 'true'`,
          { timeout: 5000 },
        )
      }

      return true
    }
    catch (error: unknown) {
      console.error('Error liking tweet:', error)
      throw new Error(`Failed to like tweet: ${errorToMessage(error)}`)
    }
  }

  /**
   * Retweets a tweet with the given ID
   */
  async function retweet(tweetId: string): Promise<boolean> {
    try {
      const page = ctx.page
      await page.goto(`${TWITTER_BASE_URL}/i/status/${tweetId}`)
      await page.waitForSelector(SELECTORS.TIMELINE.TWEET)

      // Click retweet button to open modal
      const retweetButton = await page.$(SELECTORS.TIMELINE.RETWEET_BUTTON)
      if (!retweetButton) {
        throw new Error('Retweet button not found')
      }

View on GitHub (pinned to 27111382b4)

Solutions

  1. Read the wrapped message — 'Like button not found' → fix selectors (see error 177); a waitForFunction timeout → like did not register, retry or increase the timeout.
  2. Increase the waitForFunction timeout (currently 5000 ms) for slow connections.
  3. Retry the like after a short delay for transient throttling.
  4. Confirm the account has write permission (not view-only/limited).

Example fix

// before
catch (error) {
  console.error('Error liking tweet:', error)
  throw new Error(`Failed to like tweet: ${errorToMessage(error)}`)
}

// after — preserve cause, retry once on registration timeout
catch (error) {
  if (/waitForFunction/i.test(errorToMessage(error))) {
    await sleep(1500)
    // one retry of the click+wait
  }
  throw new Error(`Failed to like tweet: ${errorToMessage(error)}`, { cause: error })
}
Defensive patterns

Strategy: retry

Type guard

function isLikeTweetError(e: unknown): boolean {
  return e instanceof Error && /Failed to like tweet:/.test(e.message)
}

Try / catch

try {
  await tweetServices.tweet.likeTweet(tweetId)
} catch (e) {
  if (e instanceof Error && /Failed to like tweet:/.test(e.message)) {
    await sleep(2000)
    return await tweetServices.tweet.likeTweet(tweetId) // one retry for transient throttling
  }
  throw e
}

Prevention

When it happens

Trigger: The like button was clicked but the aria-pressed state did not flip to 'true' within 5s (waitForFunction timeout); 'Like button not found' propagated from the inner check; the click threw because the element detached; the page navigated away during the wait.

Common situations: X rate-limits or throttles the like action so the state never updates; network lag exceeds the 5s window; the tweet is already liked but aria-pressed read falsely as 'false' (stale read); selector drift on aria-pressed; the session is read-only (view-only/locked account).

Related errors


AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12). Data as JSON: /api/errors/4df21cd49522b071. Report an issue: GitHub.