moeru-ai/airi · error · Error

Tweet text is empty. Please provide text to post.

Error message

Tweet text is empty. Please provide text to post.

What it means

Thrown by handlePostTweet (the AIRI adapter) when the parsed command's content is falsy — i.e. the user wrote 'post tweet:' with no text after the colon. This is a plain Error raised before any network call, so no API request is attempted. The same input-text event that drives all X commands reaches this handler via the adapter's handleInput switch.

Source

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

    // Handle authentication
    this.client.onEvent('module:authenticated', async (event) => {
      if (event.data.authenticated) {
        logger.main.log('X module authenticated with AIRI server')
      }
      else {
        logger.main.warn('X module authentication failed')
      }
    })
  }

  private async handlePostTweet(content: string): Promise<void> {
    if (content) {
      await this.twitterServices.tweet.postTweet(content)
      logger.main.log('Posted tweet:', content)
    }
    else {
      throw new Error('Tweet text is empty. Please provide text to post.')
    }
  }

  private async handleSearchTweets(content: string): Promise<boolean> {
    if (content) {
      const tweets = await this.twitterServices.tweet.searchTweets(content)
      logger.main.log(`Found ${tweets.length} tweets for query: ${content}`)
      // Return results to the user
      this.client.send({
        type: 'input:text',
        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 {

View on GitHub (pinned to 27111382b4)

Solutions

  1. Ensure non-empty text follows 'post tweet:' in the input.
  2. Validate the parsed content length before dispatching to handlePostTweet and prompt the user for the body.
  3. Guard in the adapter: if !content?.trim(), reply with a usage hint instead of throwing.

Example fix

// before
private async handlePostTweet(content: string): Promise<void> {
  if (content) { /* ... */ } else {
    throw new Error('Tweet text is empty. Please provide text to post.')
  }
}

// after — trim and give a friendly reply instead of throwing
private async handlePostTweet(content: string): Promise<void> {
  const text = content?.trim()
  if (!text) {
    this.client.send({ type: 'input:text', data: { text: 'Usage: post tweet: <your text>' } })
    return
  }
  await this.twitterServices.tweet.postTweet(text)
}
Defensive patterns

Strategy: validation

Validate before calling

const text = (content ?? '').trim()
if (!text) {
  // reprompt the user instead of calling handlePostTweet
  throw new Error('Tweet text required')
}
await adapter.handlePostTweet(text)

Type guard

function isEmptyTweetTextError(e: unknown): boolean {
  return e instanceof Error && /Tweet text is empty/.test(e.message)
}

Try / catch

try {
  await this.handlePostTweet(content)
} catch (e) {
  if (e instanceof Error && /Tweet text is empty/.test(e.message)) {
    this.client.send({ type: 'input:text', data: { text: 'Usage: post tweet: <your text>' } })
  } else throw e
}

Prevention

When it happens

Trigger: User sends exactly 'post tweet:' or 'post tweet: ' (whitespace-only trims to empty); parseTwitterCommand matched the 'post tweet' prefix but produced an empty content string.

Common situations: User accidentally submitted before typing the body; LLM-generated command truncated the payload; the parser strips too aggressively; UI sent an empty text field after the prefix.

Related errors


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