mastra-ai/mastra · error

Unsupported tool type: ${exhaustiveCheck}

Error message

Unsupported tool type: ${exhaustiveCheck}

What it means

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.

Source

Thrown at packages/core/src/stream/aisdk/v5/compat/prepare-tools.ts:220

                // still forward these tools to an AI SDK v6 / V3 model later. Actual
                // V2 model calls strip this field at the AISDKV5LanguageModel boundary.
                ...(strict != null ? { strict } : {}),
                providerOptions: sdkTool.providerOptions,
              };
            case 'provider-defined': {
              // Fallback for tools that pass through toolFn and still get recognized as provider-defined
              const providerId = (sdkTool as any).id;
              const providerName = (sdkTool as any).name ?? name;
              return {
                type: providerToolType,
                name: providerName,
                id: providerId,
                args: (sdkTool as any).args,
              } as PreparedTool;
            }
            default: {
              const exhaustiveCheck: never = toolType;
              throw new Error(`Unsupported tool type: ${exhaustiveCheck}`);
            }
          }
        } catch (e) {
          console.error('Error preparing tool', e);
          return null;
        }
      })
      .filter((tool): tool is PreparedTool => tool !== null),
    toolChoice:
      toolChoice == null
        ? { type: 'auto' }
        : typeof toolChoice === 'string'
          ? { type: toolChoice }
          : { type: 'tool' as const, toolName: toolChoice.toolName as string },
  };
}

/**

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Use the Mastra/tool() helpers to construct tools so the type is one of the supported values
  2. Log the offending tool's type field and remove or convert unsupported tools before passing to the agent
  3. Upgrade @mastra/core / AI SDK packages so new tool types are supported
  4. 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

Example fix

// before
const tools = { myTool: { type: 'custom', execute: fn } };
agent.stream({ messages }, { tools });
// after
const tools = { myTool: createTool({ id: 'myTool', execute: ... }) };
agent.stream({ messages }, { tools });
Defensive patterns

Strategy: type-guard

Validate before calling

const SUPPORTED_TOOL_TYPES = new Set(['function', 'dynamic', ...]);
function assertSupportedTools(tools: Record<string, unknown>) {
  for (const [name, t] of Object.entries(tools)) {
    if (!SUPPORTED_TOOL_TYPES.has((t as any).type)) {
      throw new Error(`Tool "${name}" has unsupported type ${(t as any).type}`);
    }
  }
}

Type guard

function isSupportedTool(t: unknown): t is { type: 'function' } & Record<string, unknown> {
  return typeof t === 'object' && t !== null && (t as any).type === 'function';
}

Try / catch

const prepared = Object.fromEntries(
  Object.entries(tools).filter(([, t]) => isSupportedTool(t))
);
try {
  await agent.stream({ messages }, { tools: prepared });
} catch (e) {
  logger.error('Tool preparation failed', { tools: Object.keys(prepared), e });
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/4a25ae82c81b71fb. Report an issue: GitHub.