mastra-ai/mastra · error

Model "${this.options.model}" is not available. Available mo

Error message

Model "${this.options.model}" is not available. Available models: ${ids}

What it means

The version exists but its stored agentId differs from the :agentId path parameter; the handler intentionally returns the same 404 wording as the not-exists case to avoid leaking cross-agent version existence.

Source

Thrown at agent-sdks/acp/src/connection.ts:308

      throw this.withStderr(error);
    }
  }

  private async initializeSession(): Promise<void> {
    await this.connection!.initialize(this.getInitializeRequest());

    if (this.options.authMethodId) {
      await this.connection!.authenticate({ methodId: this.options.authMethodId });
    }

    this.session = await this.connection!.newSession(this.getNewSessionRequest());

    if (this.options.model) {
      const available = this.session.models?.availableModels;

      if (available && !available.some(m => m.modelId === this.options.model)) {
        const ids = available.map(m => m.modelId).join(', ') || '(none)';
        throw new Error(`Model "${this.options.model}" is not available. Available models: ${ids}`);
      }

      await this.connection!.unstable_setSessionModel({
        sessionId: this.session.sessionId,
        modelId: this.options.model,
      });
    }
  }

  private getInitializeRequest(): InitializeRequest {
    return {
      protocolVersion: PROTOCOL_VERSION,
      clientCapabilities: {
        fs: { readTextFile: true, writeTextFile: true },
      },
      clientInfo: {
        name: '@mastra/acp',
        version: '0.1.0',

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Verify the versionId was obtained from the same agent's version list
  2. Correct the :agentId path parameter to match version.agentId
  3. Refresh client state so agentId and versionId come from the same fetch
  4. Add client-side checks pairing version.agentId with the selected agent before calling

Example fix

// before
restoreAgentVersion(agent.id, selectedVersion.id); // selectedVersion from another agent
// after
if (selectedVersion.agentId === agent.id) {
  restoreAgentVersion(agent.id, selectedVersion.id);
}
Defensive patterns

Strategy: validation

Validate before calling

const versions = await fetch(`/api/agents/${agentId}/versions`).then(r => r.json());
const v = versions.find(x => x.id === versionId);
if (!v) throw new Error(`Version ${versionId} is not owned by agent ${agentId}`);

Type guard

function belongsToAgent(v: {agentId: string} | undefined, agentId: string): v is {agentId: string} {
  return !!v && v.agentId === agentId;
}

Try / catch

try {
  await fetch(`/api/agents/${agentId}/versions/${versionId}`);
} catch (e) {
  if (isHttpError(e) && e.status === 404 && e.message.includes('not found for agent')) {
    // re-pair agentId and versionId in client state
  } else throw e;
}

Prevention

When it happens

Trigger: GET/POST /api/agents/:agentId/versions/:versionId where versionId belongs to a different agent than the one in the path.

Common situations: Client state mixing an agent id from one request with a versionId from another agent's response; copy/paste across tabs; UI bugs pairing the wrong list items.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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