{"record":{"id":"78d908b896e8d542","repo":"moeru-ai/airi","slug":"search-query-is-empty-please-provide-a-query-to-s","errorCode":null,"errorMessage":"Search query is empty. Please provide a query to search.","messagePattern":"Search query is empty\\. Please provide a query to search\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"integrations/twitter-services/src/adapters/airi-adapter.ts","lineNumber":158,"sourceCode":"    }\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 {\n      throw new Error('Search query is empty. Please provide a query to search.')\n    }\n  }\n\n  private async handleLikeTweet(content: string): Promise<void> {\n    if (content) {\n      await this.twitterServices.tweet.likeTweet(content)\n      logger.main.log(`Liked tweet: ${content}`)\n    }\n    else {\n      throw new Error('Tweet ID is empty. Please provide a tweet ID to like.')\n    }\n  }\n\n  private async handleRetweet(content: string): Promise<void> {\n    if (content) {\n      await this.twitterServices.tweet.retweet(content)\n      logger.main.log(`Retweeted: ${content}`)\n    }","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/moeru-ai/airi/blob/27111382b4a79a7e983289d6e983a06af185ed0f/integrations/twitter-services/src/adapters/airi-adapter.ts#L140-L176","documentation":"Thrown by handleSearchTweets when the parsed command's content is falsy — i.e. 'search tweets:' was sent with no query string. This is a plain Error raised before any browser/API call; no search is executed.","triggerScenarios":"User sends 'search tweets:' or 'search tweets:   ' (whitespace-only); parseTwitterCommand matched the 'search tweets' prefix but content trimmed to empty.","commonSituations":"Premature submit; parser dropped the query payload; LLM emitted only the command keyword; empty input forwarded by the AIRI input:text event.","solutions":["Provide a non-empty query after 'search tweets:'.","Validate content in the parser and reject/reprompt before reaching the handler.","Have the adapter reply with usage guidance instead of throwing on empty content."],"exampleFix":"// before\nif (content) { /* search */ } else {\n  throw new Error('Search query is empty. Please provide a query to search.')\n}\n\n// after\nconst q = content?.trim()\nif (!q) {\n  this.client.send({ type: 'input:text', data: { text: 'Usage: search tweets: <query>' } })\n  return false\n}","handlingStrategy":"validation","validationCode":"const q = (content ?? '').trim()\nif (!q) {\n  throw new Error('Search query required')\n}\nawait adapter.handleSearchTweets(q)","typeGuard":"function isEmptySearchQueryError(e: unknown): boolean {\n  return e instanceof Error && /Search query is empty/.test(e.message)\n}","tryCatchPattern":"try {\n  await this.handleSearchTweets(content)\n} catch (e) {\n  if (e instanceof Error && /Search query is empty/.test(e.message)) {\n    this.client.send({ type: 'input:text', data: { text: 'Usage: search tweets: <query>' } })\n  } else throw e\n}","preventionTips":["Validate the parsed query length in the parser and reprompt.","Reply with usage guidance instead of throwing on empty input.","Send only complete 'search tweets: <query>' strings."],"tags":["twitter","validation","search","adapter","empty-input"],"backgroundTag":null,"analyzedSha":"27111382b4a79a7e983289d6e983a06af185ed0f","analyzedAt":"2026-08-12T18:33:34.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}