mastra-ai/mastra · error

prepareStep returned an unsupported model version

Error message

prepareStep returned an unsupported model version

What it means

In the tool-loop agent's step pipeline, prepareStep may override the model for the next step. When it does, the agent resolves the configured model via resolveModelConfig and verifies it is a supported LanguageModel version (isSupportedLanguageModel). If the resolved value is not a supported language model instance (wrong spec version or not a model at all), the loop throws because it cannot run the step with an incompatible model object.

Source

Thrown at packages/core/src/tool-loop-agent/tool-loop-processor.ts:273

        // experimental_context: this.settings.experimental_context,
        // experimental_download: this.settings.experimental_download,
      };

      // Call prepareCall and apply any returned overrides
      const prepareCallResult = await this.settings.prepareCall(prepareCallInput as any); // TODO: types
      this.prepareCallResult = prepareCallResult;
    }
  }

  private async handlePrepareStep(args: ProcessInputStepArgs, currentResult: ProcessInputStepResult) {
    if (this.settings.prepareStep) {
      const { messages, steps, stepNumber } = args;

      let model = args.model;
      if (currentResult.model) {
        const resolvedModel = await resolveModelConfig(currentResult.model);
        if (!isSupportedLanguageModel(resolvedModel)) {
          throw new Error('prepareStep returned an unsupported model version');
        }
        model = resolvedModel;
      }

      // Use the model from currentResult if prepareCall overrode it, otherwise use args.model

      // Note: We pass messages and steps in Mastra format rather than converting to AI SDK format.
      // This is intentional - most prepareStep callbacks only return overrides and don't inspect
      // the message content. The type casts handle the format difference at runtime.
      const prepareStepInputArgs: {
        /**
         * The steps that have been executed so far.
         */
        steps: Array<StepResult<NoInfer<any>>>;
        /**
         * The number of the step that is being executed.
         */
        stepNumber: number;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Return a supported LanguageModel instance from prepareStep (create it with the same helper/factory the agent itself uses, e.g. resolveModelConfig or a compatible provider method).
  2. If overriding by ID, ensure the ID exists in the configured model registry/config so resolveModelConfig resolves it to a supported model.
  3. Upgrade or downgrade the model package so the spec version matches what isSupportedLanguageModel accepts (typically LanguageModelV2/V3-era for current core).
  4. Log/inspect the resolved value before returning it: const m = await resolveModelConfig(candidate); console.log(m) to confirm it's a model, not a wrapper.

Example fix

// before
prepareStep: async () => ({ model: 'gpt-4o-mini-vision-preview' }), // unresolvable/unsupported

// after
prepareStep: async () => ({ model: await resolveModelConfig('openai/gpt-4o-mini') }),
Defensive patterns

Strategy: validation

Validate before calling

import { resolveModelConfig, isSupportedLanguageModel } from '@mastra/core';
async function assertOverridable(modelId: unknown): Promise<void> {
  const resolved = await resolveModelConfig(modelId as any);
  if (!isSupportedLanguageModel(resolved)) {
    throw new TypeError(`prepareStep model override not supported: ${String(modelId)}`);
  }
}

Type guard

function isSupported(m: unknown): m is LanguageModel {
  // mirror core's check: has the expected spec version and doGenerate/doStream
  return !!m && typeof m === 'object' && 'specificationVersion' in m && typeof (m as any).doStream === 'function';
}

Try / catch

try {
  await agent.stream({ ... });
} catch (err) {
  if (err instanceof Error && err.message === 'prepareStep returned an unsupported model version') {
    console.error('prepareStep model override is unsupported; return a supported LanguageModel');
  } else throw err;
}

Prevention

When it happens

Trigger: Returning currentResult.model from a prepareStep callback with a value that resolves to an unsupported model: e.g. a model ID string not resolvable in the model config registry, a v1-spec model where only v2/v3 is supported, or a non-model object (provider wrapper, options bag) passed as the model.

Common situations: Upgrading @mastra/core or the AI SDK so model spec versions changed while prepareStep still returns old-style model objects; passing a model name string that isn't registered in the model config; dynamic model switching logic that returns provider objects instead of resolved models.

Related errors


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