moeru-ai/airi · error

Failed to get tweet details: ${errorToMessage(error)}

Error message

Failed to get tweet details: ${errorToMessage(error)}

What it means

This is the outer catch for getTweetDetails that re-throws any error raised during navigation, element selection, parsing, or reply scraping as a single normalized message via errorToMessage. It is a pass-through wrapper; the real cause is one of the inner throws (182, 183) or a Puppeteer navigation/timeout error.

Source

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

      for (const replyElement of replyElements) {
        const extractedReply = await TweetParser.extractTweetData(page, replyElement)
        if (extractedReply) {
          replies.push(extractedReply)
        }
      }

      // Construct the detailed tweet
      const tweetDetail: TweetDetail = {
        ...mainTweet,
        replies: replies.length > 0 ? replies : undefined,
        quotedTweet,
      }

      return tweetDetail
    }
    catch (error: unknown) {
      console.error('Error getting tweet details:', error)
      throw new Error(`Failed to get tweet details: ${errorToMessage(error)}`)
    }
  }

  return {
    searchTweets,
    likeTweet,
    retweet,
    postTweet,
    getTweetDetails,
  }
}

View on GitHub (pinned to 27111382b4)

Solutions

  1. Inspect the console.error output (already logged) to see whether the cause is navigation, element-not-found, or parser failure, then address that specific inner error.
  2. Wrap the reply-scraping loop so a single reply failure does not abort the whole getTweetDetails call.
  3. Validate the tweet id and session before calling, and consider a single retry on transient navigation errors.

Example fix

// before
try {
  // ... replies = await scrapeReplies(page)
  return tweetDetail
}
catch (error: unknown) {
  throw new Error(`Failed to get tweet details: ${errorToMessage(error)}`)
}

// after
let replies: Tweet[] = []
try {
  replies = await scrapeReplies(page)
}
catch (replyError) {
  console.warn('Reply scraping failed; returning tweet without replies:', replyError)
}
return { ...mainTweet, replies: replies.length > 0 ? replies : undefined, quotedTweet }
Defensive patterns

Strategy: try-catch

Try / catch

try {
  return await getTweetDetails(tweetId)
}
catch (err) {
  // distinguish transient navigation errors from permanent ones
  if (/net::ERR|Navigation timeout/i.test((err as Error).message)) {
    return getTweetDetails(tweetId) // single retry
  }
  throw err
}

Prevention

When it happens

Trigger: Any uncaught error from page.goto, waitForSelector, TweetParser.extractTweetData, reply extraction, or the inner 'Tweet element not found'/'Failed to extract tweet data' throws propagates here and is rewrapped.

Common situations: Network/proxy failure during page.goto; the inner errors 182/183 bubble up; reply selector changes cause the reply loop to throw; long thread where reply scraping times out.

Related errors


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