{"record":{"id":"94e2dca447926f6e","repo":"ComposioHQ/composio","slug":"provide-query-or-recipients-to-find-an-imessage-th","errorCode":null,"errorMessage":"Provide query or recipients to find an iMessage thread.","messagePattern":"Provide query or recipients to find an iMessage thread\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"ts/packages/cli-local-tools/src/toolkits/beeper-imessage.ts","lineNumber":934,"sourceCode":"      inputParams: listThreadsInput,\n      execute: async (input, context) => {\n        const raw = await runImessageCli('threads', withCursorArgs(input, []), input, context);\n        return compactThreadsResult(raw, {\n          compact: input.compact,\n          includeRaw: input.includeRaw,\n          resolveContactNames: input.resolveContactNames,\n        });\n      },\n    }),\n    nativeTool({\n      slug: 'FIND_THREAD',\n      name: 'Find iMessage thread',\n      description:\n        'Find threads by contact name, phone/email, thread title, or participants without doing a manual LIST_THREADS pagination/filter dance.',\n      inputParams: findThreadInput,\n      execute: async (input, context) => {\n        if (!input.query && (!input.recipients || input.recipients.length === 0)) {\n          throw new Error('Provide query or recipients to find an iMessage thread.');\n        }\n        const scan = await scanThreads({\n          input,\n          context,\n          query: input.query,\n          recipients: input.recipients,\n          maxPages: input.maxPages,\n          resolveContactNames: input.resolveContactNames,\n        });\n        const result = {\n          items: input.compact\n            ? scan.matches.map(thread => compactThread(thread, scan.labels))\n            : scan.matches,\n          pageInfo: {\n            pagesScanned: scan.pagesScanned,\n            hasMore: scan.hasMore,\n            nextBefore: scan.nextBefore,\n          },","sourceCodeStart":916,"sourceCodeEnd":952,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/cli-local-tools/src/toolkits/beeper-imessage.ts#L916-L952","documentation":"The 'Find iMessage thread' tool requires at least one search criterion: either a free-text query (name, phone, email, title) or a recipients array. Passing neither (undefined query and empty/missing recipients) is rejected before any scanning work is done.","triggerScenarios":"Calling find_thread with an empty object, with query: '' and no recipients, or with recipients: []; LLM tool calls omitting all optional-looking fields.","commonSituations":"Optional-parameter confusion — both fields look optional so callers pass neither; empty-string queries after trimming user input.","solutions":["Pass a non-empty query string (contact name, phone, email, or title)","Or pass a non-empty recipients array","Validate user input before invoking the tool so at least one criterion exists"],"exampleFix":"// before\nfindThread({});\n// after\nfindThread({ query: 'Alice' });\n// or\nfindThread({ recipients: ['+15551234567'] });","handlingStrategy":"validation","validationCode":"const hasCriterion = Boolean(query?.trim()) || (recipients?.length ?? 0) > 0;\nif (!hasCriterion) promptUserForQuery();","typeGuard":"const hasSearchCriterion = (i: { query?: string; recipients?: string[] }) =>\n  Boolean(i.query?.trim()) || (i.recipients?.length ?? 0) > 0;","tryCatchPattern":"try { ... } catch (e) { if (e.message.includes('Provide query or recipients')) askUserForCriterion(); }","preventionTips":["Require at least one search input in your UI before invoking the tool","Treat empty-string query as absent"],"tags":["validation","imessage","local-tools"],"backgroundTag":"missing-required-param","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}