{"record":{"id":"4a25ae82c81b71fb","repo":"mastra-ai/mastra","slug":"unsupported-tool-type-exhaustivecheck","errorCode":null,"errorMessage":"Unsupported tool type: ${exhaustiveCheck}","messagePattern":"Unsupported tool type: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/stream/aisdk/v5/compat/prepare-tools.ts","lineNumber":220,"sourceCode":"                // still forward these tools to an AI SDK v6 / V3 model later. Actual\n                // V2 model calls strip this field at the AISDKV5LanguageModel boundary.\n                ...(strict != null ? { strict } : {}),\n                providerOptions: sdkTool.providerOptions,\n              };\n            case 'provider-defined': {\n              // Fallback for tools that pass through toolFn and still get recognized as provider-defined\n              const providerId = (sdkTool as any).id;\n              const providerName = (sdkTool as any).name ?? name;\n              return {\n                type: providerToolType,\n                name: providerName,\n                id: providerId,\n                args: (sdkTool as any).args,\n              } as PreparedTool;\n            }\n            default: {\n              const exhaustiveCheck: never = toolType;\n              throw new Error(`Unsupported tool type: ${exhaustiveCheck}`);\n            }\n          }\n        } catch (e) {\n          console.error('Error preparing tool', e);\n          return null;\n        }\n      })\n      .filter((tool): tool is PreparedTool => tool !== null),\n    toolChoice:\n      toolChoice == null\n        ? { type: 'auto' }\n        : typeof toolChoice === 'string'\n          ? { type: toolChoice }\n          : { type: 'tool' as const, toolName: toolChoice.toolName as string },\n  };\n}\n\n/**","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/stream/aisdk/v5/compat/prepare-tools.ts#L202-L238","documentation":"prepareToolsAndToolChoice maps known tool types to provider-specific prepared tools; the default branch is a compile-time exhaustiveness guard (const exhaustiveCheck: never = toolType). It fires at runtime when a tool's type isn't one of the supported variants — typically a dynamically-cast or provider-specific tool object that skipped schema validation.","triggerScenarios":"Passing a tool object whose 'type' field is an unexpected string (e.g. custom plugin tool type, provider-specific 'provider-defined' tool) into agent generation; using tools built by a different AI SDK version with a new type variant.","commonSituations":"Mixing AI SDK v4 and v5 tool shapes; hand-writing tool objects instead of using the tool() helper; third-party integrations adding new tool types not yet mapped here.","solutions":["Use the Mastra/tool() helpers to construct tools so the type is one of the supported values","Log the offending tool's type field and remove or convert unsupported tools before passing to the agent","Upgrade @mastra/core / AI SDK packages so new tool types are supported","Wrap tool preparation in try/catch — note this call site already catches and returns null, so check why the tool disappeared from the prepared list"],"exampleFix":"// before\nconst tools = { myTool: { type: 'custom', execute: fn } };\nagent.stream({ messages }, { tools });\n// after\nconst tools = { myTool: createTool({ id: 'myTool', execute: ... }) };\nagent.stream({ messages }, { tools });","handlingStrategy":"type-guard","validationCode":"const SUPPORTED_TOOL_TYPES = new Set(['function', 'dynamic', ...]);\nfunction assertSupportedTools(tools: Record<string, unknown>) {\n  for (const [name, t] of Object.entries(tools)) {\n    if (!SUPPORTED_TOOL_TYPES.has((t as any).type)) {\n      throw new Error(`Tool \"${name}\" has unsupported type ${(t as any).type}`);\n    }\n  }\n}","typeGuard":"function isSupportedTool(t: unknown): t is { type: 'function' } & Record<string, unknown> {\n  return typeof t === 'object' && t !== null && (t as any).type === 'function';\n}","tryCatchPattern":"const prepared = Object.fromEntries(\n  Object.entries(tools).filter(([, t]) => isSupportedTool(t))\n);\ntry {\n  await agent.stream({ messages }, { tools: prepared });\n} catch (e) {\n  logger.error('Tool preparation failed', { tools: Object.keys(prepared), e });\n  throw e;\n}","preventionTips":["Create tools with createTool/tool() helpers rather than hand-written objects","Don't mix AI SDK v4 and v5 tool shapes in one codebase","After upgrades, smoke-test agents that pass custom tools","Filter unsupported tool types out at config-load time with a type guard"],"tags":["tools","exhaustiveness","aisdk","internals"],"backgroundTag":"unsupported-tool-type","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}