{"record":{"id":"5830d6a0690a9321","repo":"mastra-ai/mastra","slug":"preparestep-returned-an-unsupported-model-version","errorCode":null,"errorMessage":"prepareStep returned an unsupported model version","messagePattern":"prepareStep returned an unsupported model version","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/tool-loop-agent/tool-loop-processor.ts","lineNumber":273,"sourceCode":"        // experimental_context: this.settings.experimental_context,\n        // experimental_download: this.settings.experimental_download,\n      };\n\n      // Call prepareCall and apply any returned overrides\n      const prepareCallResult = await this.settings.prepareCall(prepareCallInput as any); // TODO: types\n      this.prepareCallResult = prepareCallResult;\n    }\n  }\n\n  private async handlePrepareStep(args: ProcessInputStepArgs, currentResult: ProcessInputStepResult) {\n    if (this.settings.prepareStep) {\n      const { messages, steps, stepNumber } = args;\n\n      let model = args.model;\n      if (currentResult.model) {\n        const resolvedModel = await resolveModelConfig(currentResult.model);\n        if (!isSupportedLanguageModel(resolvedModel)) {\n          throw new Error('prepareStep returned an unsupported model version');\n        }\n        model = resolvedModel;\n      }\n\n      // Use the model from currentResult if prepareCall overrode it, otherwise use args.model\n\n      // Note: We pass messages and steps in Mastra format rather than converting to AI SDK format.\n      // This is intentional - most prepareStep callbacks only return overrides and don't inspect\n      // the message content. The type casts handle the format difference at runtime.\n      const prepareStepInputArgs: {\n        /**\n         * The steps that have been executed so far.\n         */\n        steps: Array<StepResult<NoInfer<any>>>;\n        /**\n         * The number of the step that is being executed.\n         */\n        stepNumber: number;","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/tool-loop-agent/tool-loop-processor.ts#L255-L291","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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).","If overriding by ID, ensure the ID exists in the configured model registry/config so resolveModelConfig resolves it to a supported model.","Upgrade or downgrade the model package so the spec version matches what isSupportedLanguageModel accepts (typically LanguageModelV2/V3-era for current core).","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."],"exampleFix":"// before\nprepareStep: async () => ({ model: 'gpt-4o-mini-vision-preview' }), // unresolvable/unsupported\n\n// after\nprepareStep: async () => ({ model: await resolveModelConfig('openai/gpt-4o-mini') }),","handlingStrategy":"validation","validationCode":"import { resolveModelConfig, isSupportedLanguageModel } from '@mastra/core';\nasync function assertOverridable(modelId: unknown): Promise<void> {\n  const resolved = await resolveModelConfig(modelId as any);\n  if (!isSupportedLanguageModel(resolved)) {\n    throw new TypeError(`prepareStep model override not supported: ${String(modelId)}`);\n  }\n}","typeGuard":"function isSupported(m: unknown): m is LanguageModel {\n  // mirror core's check: has the expected spec version and doGenerate/doStream\n  return !!m && typeof m === 'object' && 'specificationVersion' in m && typeof (m as any).doStream === 'function';\n}","tryCatchPattern":"try {\n  await agent.stream({ ... });\n} catch (err) {\n  if (err instanceof Error && err.message === 'prepareStep returned an unsupported model version') {\n    console.error('prepareStep model override is unsupported; return a supported LanguageModel');\n  } else throw err;\n}","preventionTips":["Resolve model overrides through the same resolveModelConfig path the agent uses.","Only return model instances from the installed, version-matched provider packages.","After upgrading mastra/AI SDK, update prepareStep model factories to the new spec version.","Validate overrides in tests by calling resolveModelConfig + isSupportedLanguageModel on them."],"tags":["agent","prepare-step","model-version","configuration"],"backgroundTag":"unsupported-model-version","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}