{"record":{"id":"852cac14a88ebe0f","repo":"ComposioHQ/composio","slug":"invalid-tool-list-parameters-you-should-not-use-t","errorCode":null,"errorMessage":"Invalid tool list parameters. You should not use tools and toolkits filter together.","messagePattern":"Invalid tool list parameters\\. You should not use tools and toolkits filter together\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"ts/packages/core/src/models/Tools.ts","lineNumber":493,"sourceCode":"   *\n   * // Search for tools\n   * const searchResults = await composio.tools.getRawComposioTools({\n   *   search: 'user management'\n   * });\n   *\n   * // Get tools by authentication config\n   * const authSpecificTools = await composio.tools.getRawComposioTools({\n   *   authConfigIds: ['auth_config_123']\n   * });\n   * ```\n   */\n  async getRawComposioTools(\n    query: ToolListParams,\n    options?: SchemaModifierOptions,\n    requestOptions?: ComposioRequestOptions\n  ): Promise<ToolList> {\n    if ('tools' in query && 'toolkits' in query) {\n      throw new ValidationError(\n        'Invalid tool list parameters. You should not use tools and toolkits filter together.'\n      );\n    }\n\n    const queryParams = ToolListParamsSchema.safeParse(query);\n    if (queryParams.error) {\n      throw new ValidationError('Invalid tool list parameters', {\n        cause: queryParams.error,\n      });\n    }\n\n    const shouldAutoApplyImportant =\n      'toolkits' in queryParams.data &&\n      !('tools' in queryParams.data) &&\n      !('tags' in queryParams.data) &&\n      !('search' in queryParams.data) &&\n      // if the user provides a limit, do not apply the important flag\n      !('limit' in queryParams.data) &&","sourceCodeStart":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/core/src/models/Tools.ts#L475-L511","documentation":"ValidationError thrown by getRawComposioTools when the query object contains both 'tools' and 'toolkits' filters simultaneously. The backend cannot combine both filters, so the SDK rejects the combination up front.","triggerScenarios":"Calling composio.tools.get({ tools: ['github_star_repo'], toolkits: ['github'] }) or getRawComposioTools with both keys present, including keys set to undefined via spread/destructuring.","commonSituations":"Building filter objects dynamically where both keys get set, merging config objects, porting code that assumed filters were ANDed.","solutions":["Use only one of tools or toolkits in the query","If dynamic, delete keys whose value is undefined/empty before passing","Use search or authConfigIds as additional filters instead of combining tools+toolkits"],"exampleFix":"// before\ncomposio.tools.get({ tools: ['github_star_repo'], toolkits: ['github'] })\n// after\ncomposio.tools.get({ tools: ['github_star_repo'] })","handlingStrategy":"validation","validationCode":"const q: ToolListParams = {};\nif (slugs) q.tools = slugs; else if (toolkitSlugs) q.toolkits = toolkitSlugs; // never both","typeGuard":"const hasBothFilters = (q: object): q is { tools: unknown; toolkits: unknown } => 'tools' in q && 'toolkits' in q;","tryCatchPattern":"try { await composio.tools.get(query); } catch (e) { if (e instanceof ValidationError && /tools and toolkits/.test(e.message)) dropOneFilter(query); else throw e; }","preventionTips":["Build filter objects with if/else so keys are mutually exclusive","Delete empty/undefined keys before passing queries"],"tags":["validation","tool-filter","typescript"],"backgroundTag":"mutually-exclusive-parameters","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}