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
- 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.
- Increase the waitForFunction timeout (currently 5000 ms) for slow connections.
- Retry the like after a short delay for transient throttling.
- 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
- Increase the 5000 ms waitForFunction window on slow connections.
- Retry once after a short delay to absorb X throttling.
- Confirm the account has write permission (not view-only/limited).
- Preserve the original cause via the Error options bag for diagnosis.
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
- Failed to search tweets: ${errorToMessage(error)}
- Like button not found
- Tweet ID is empty. Please provide a tweet ID to like.
- Retweet button not found
- Failed to retweet: ${errorToMessage(error)}
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/4df21cd49522b071.
Report an issue: GitHub.