{"record":{"id":"db19af65c9bf48b3","repo":"moeru-ai/airi","slug":"tweet-text-is-empty-please-provide-text-to-post","errorCode":null,"errorMessage":"Tweet text is empty. Please provide text to post.","messagePattern":"Tweet text is empty\\. Please provide text to post\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"integrations/twitter-services/src/adapters/airi-adapter.ts","lineNumber":139,"sourceCode":"\n    // Handle authentication\n    this.client.onEvent('module:authenticated', async (event) => {\n      if (event.data.authenticated) {\n        logger.main.log('X module authenticated with AIRI server')\n      }\n      else {\n        logger.main.warn('X module authentication failed')\n      }\n    })\n  }\n\n  private async handlePostTweet(content: string): Promise<void> {\n    if (content) {\n      await this.twitterServices.tweet.postTweet(content)\n      logger.main.log('Posted tweet:', content)\n    }\n    else {\n      throw new Error('Tweet text is empty. Please provide text to post.')\n    }\n  }\n\n  private async handleSearchTweets(content: string): Promise<boolean> {\n    if (content) {\n      const tweets = await this.twitterServices.tweet.searchTweets(content)\n      logger.main.log(`Found ${tweets.length} tweets for query: ${content}`)\n      // Return results to the user\n      this.client.send({\n        type: 'input:text',\n        data: {\n          text: `Found ${tweets.length} tweets for '${content}':\n${tweets.slice(0, 5).map((t: Tweet) => `- ${t.text.substring(0, 100)}...`).join('\\n')}`,\n        },\n      })\n      return true\n    }\n    else {","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/moeru-ai/airi/blob/27111382b4a79a7e983289d6e983a06af185ed0f/integrations/twitter-services/src/adapters/airi-adapter.ts#L121-L157","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure non-empty text follows 'post tweet:' in the input.","Validate the parsed content length before dispatching to handlePostTweet and prompt the user for the body.","Guard in the adapter: if !content?.trim(), reply with a usage hint instead of throwing."],"exampleFix":"// before\nprivate async handlePostTweet(content: string): Promise<void> {\n  if (content) { /* ... */ } else {\n    throw new Error('Tweet text is empty. Please provide text to post.')\n  }\n}\n\n// after — trim and give a friendly reply instead of throwing\nprivate async handlePostTweet(content: string): Promise<void> {\n  const text = content?.trim()\n  if (!text) {\n    this.client.send({ type: 'input:text', data: { text: 'Usage: post tweet: <your text>' } })\n    return\n  }\n  await this.twitterServices.tweet.postTweet(text)\n}","handlingStrategy":"validation","validationCode":"const text = (content ?? '').trim()\nif (!text) {\n  // reprompt the user instead of calling handlePostTweet\n  throw new Error('Tweet text required')\n}\nawait adapter.handlePostTweet(text)","typeGuard":"function isEmptyTweetTextError(e: unknown): boolean {\n  return e instanceof Error && /Tweet text is empty/.test(e.message)\n}","tryCatchPattern":"try {\n  await this.handlePostTweet(content)\n} catch (e) {\n  if (e instanceof Error && /Tweet text is empty/.test(e.message)) {\n    this.client.send({ type: 'input:text', data: { text: 'Usage: post tweet: <your text>' } })\n  } else throw e\n}","preventionTips":["Trim and validate parsed content in parseTwitterCommand before dispatch.","Reply with usage hints instead of throwing on empty input.","Ensure the UI/LLM always sends the body after the command prefix."],"tags":["twitter","validation","adapter","empty-input"],"backgroundTag":null,"analyzedSha":"27111382b4a79a7e983289d6e983a06af185ed0f","analyzedAt":"2026-08-12T18:33:34.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}