mastra-ai/mastra · error
No model selected. Use /models to select a model first.
Error message
No model selected. Use /models to select a model first.
What it means
getDynamicModel throws this when a controller session context exists but no modelId is set in it — i.e. the user has a session but never picked a model. The message directs them to the /models command.
Source
Thrown at mastracode/sdk/src/agents/model.ts:219
*/
export function getDynamicModel(
{ requestContext }: { requestContext: RequestContext },
settingsPath?: string,
): ResolvedModel {
const agentControllerContext = requestContext.get('controller') as AgentControllerRequestContext<any> | undefined;
const modelId = agentControllerContext?.session?.modelId;
if (!modelId) {
// A missing controller context means the run was started without session
// request context at all (e.g. a signal delivered to an idle thread) —
// "use /models" would mislead there, the user's selection was never the
// problem.
if (!agentControllerContext) {
throw new Error(
'No model available: this run started without a controller session context, so no model selection could be resolved.',
);
}
throw new Error('No model selected. Use /models to select a model first.');
}
const thinkingLevel = resolveRequestThinkingLevel(agentControllerContext, settingsPath);
return resolveModel(modelId, { thinkingLevel, remapForCodexOAuth: true, requestContext });
}
/**
* Goal judge model resolver for the agent's `goal.judge` config. Resolves the
* configured goal judge model through mastracode's gateway so provider
* credentials (stored in auth storage, not just env) are injected — a bare model
* id handed to core's default model router would fail to find the API key.
*
* Returns `undefined` when no judge model is configured, which keeps the goal
* step a complete no-op (the goal mechanism requires a judge to do anything).
*
* `settingsPath` must be the same source `createMastraCode()` reads from so the
* judge model and the goal budget (`goalMaxTurns`) come from one config — with aView on GitHub (pinned to 75dd419e61)
Solutions
- Run /models in the session and select a model
- Configure a default model for new sessions so modelId is pre-populated
- Re-select the model if a config migration cleared it
- Check why modelId was cleared if a selection was previously made (settings persistence issue)
Example fix
// before (in TUI) > run tests with the agent // no model chosen yet // after > /models → select anthropic/claude-sonnet-4 > run tests with the agent
Defensive patterns
Strategy: validation
Validate before calling
if (agentControllerContext && !agentControllerContext.modelId) {
throw new Error('select a model with /models before running');
} Type guard
const hasModelSelection = (ctx: AgentControllerContext | null): boolean => Boolean(ctx?.modelId);
Try / catch
try {
await runAgent(task);
} catch (err) {
if ((err as Error).message.includes('No model selected')) {
console.error('Run /models to pick a model first');
} else throw err;
} Prevention
- Configure a default model for new sessions
- Check session state before actions that need the model
- Surface model-selection UI early in onboarding
When it happens
Trigger: codeAgent → getDynamicModel sees a truthy agentControllerContext whose modelId is empty/undefined — an interactive session that has not made a model selection via /models.
Common situations: Fresh sessions where the user immediately invokes an action requiring the model, sessions where a previously selected model was cleared, or environments without a default model configured.
Related errors
- AcpAgent does not support resuming suspended generate calls
- ACP prompt stopped before completing: ${response.stopReason}
- Auth0 domain and audience are required, please provide them
- Cookie password must be at least 32 characters for SSO. Set
- Better Auth instance is required. Please provide the auth op
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/376e8085730f7a31.
Report an issue: GitHub.