moeru-ai/airi · error · Error

Tweet ID is empty. Please provide a tweet ID to like.

Error message

Tweet ID is empty. Please provide a tweet ID to like.

What it means

Thrown by handleLikeTweet when the parsed command's content is falsy — i.e. 'like tweet:' was sent with no tweet id. This is a plain Error raised before likeTweet is called, so no browser navigation occurs.

Source

Thrown at integrations/twitter-services/src/adapters/airi-adapter.ts:168

        data: {
          text: `Found ${tweets.length} tweets for '${content}':
${tweets.slice(0, 5).map((t: Tweet) => `- ${t.text.substring(0, 100)}...`).join('\n')}`,
        },
      })
      return true
    }
    else {
      throw new Error('Search query is empty. Please provide a query to search.')
    }
  }

  private async handleLikeTweet(content: string): Promise<void> {
    if (content) {
      await this.twitterServices.tweet.likeTweet(content)
      logger.main.log(`Liked tweet: ${content}`)
    }
    else {
      throw new Error('Tweet ID is empty. Please provide a tweet ID to like.')
    }
  }

  private async handleRetweet(content: string): Promise<void> {
    if (content) {
      await this.twitterServices.tweet.retweet(content)
      logger.main.log(`Retweeted: ${content}`)
    }
    else {
      throw new Error('Tweet ID is empty. Please provide a tweet ID to retweet.')
    }
  }

  private async handleGetUser(content: string): Promise<boolean> {
    if (content) {
      const userProfile = await this.twitterServices.user.getUserProfile(content)
      logger.main.log(`Retrieved profile for user: @${content}`)
      // Return user info to the user

View on GitHub (pinned to 27111382b4)

Solutions

  1. Provide a non-empty tweet id (or status URL) after 'like tweet:'.
  2. Validate content in the parser and reprompt for the id before dispatch.
  3. Have the adapter reply with usage guidance instead of throwing.

Example fix

// before
if (content) { await this.twitterServices.tweet.likeTweet(content) } else {
  throw new Error('Tweet ID is empty. Please provide a tweet ID to like.')
}

// after
const id = content?.trim()
if (!id) {
  this.client.send({ type: 'input:text', data: { text: 'Usage: like tweet: <tweetId>' } })
  return
}
Defensive patterns

Strategy: validation

Validate before calling

const id = (content ?? '').trim()
if (!id) {
  throw new Error('Tweet ID required')
}
await adapter.handleLikeTweet(id)

Type guard

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

Try / catch

try {
  await this.handleLikeTweet(content)
} catch (e) {
  if (e instanceof Error && /tweet ID to like/i.test(e.message)) {
    this.client.send({ type: 'input:text', data: { text: 'Usage: like tweet: <tweetId>' } })
  } else throw e
}

Prevention

When it happens

Trigger: User sends 'like tweet:' with nothing after the colon; parseTwitterCommand matched the 'like tweet' prefix but content is empty/whitespace.

Common situations: User forgot to paste the tweet id/status URL; LLM truncated the payload; empty input forwarded by the AIRI input:text event.

Related errors


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