mastra-ai/mastra · error · HTTPException

Version with id ${versionId} not found for MCP client ${mcpC

Error message

Version with id ${versionId} not found for MCP client ${mcpClientId}

What it means

This 404 is thrown when the retrieved version exists but its mcpClientId field does not match the mcpClientId path parameter. The API intentionally reports this ownership mismatch as 404 (not 403) to avoid leaking version existence across resources.

Source

Thrown at packages/server/src/server/handlers/mcp-client-versions.ts:200

      const storage = mastra.getStorage();

      if (!storage) {
        throw new HTTPException(500, { message: 'Storage is not configured' });
      }

      const mcpClientStore = await storage.getStore('mcpClients');
      if (!mcpClientStore) {
        throw new HTTPException(500, { message: 'MCP clients storage domain is not available' });
      }

      const version = await mcpClientStore.getVersion(versionId);

      if (!version) {
        throw new HTTPException(404, { message: `Version with id ${versionId} not found` });
      }

      if (version.mcpClientId !== mcpClientId) {
        throw new HTTPException(404, {
          message: `Version with id ${versionId} not found for MCP client ${mcpClientId}`,
        });
      }
      const mcpClient = await mcpClientStore.getById(mcpClientId);
      assertStoredResourceScope(mcpClient, await getStoredResourceScope(mastra, requestContext));

      return version;
    } catch (error) {
      return handleError(error, 'Error getting MCP client version');
    }
  },
});

/**
 * POST /stored/mcp-clients/:mcpClientId/versions/:versionId/activate - Set a version as active
 */
export const ACTIVATE_MCP_CLIENT_VERSION_ROUTE = createRoute({
  method: 'POST',

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Fetch the version through the MCP client it actually belongs to (list that client's versions)
  2. Regenerate the URL from a single source of truth for both ids
  3. Check that you did not swap client/version ids in the path

Example fix

// before
fetch(`/api/mcp-clients/${clientA.id}/versions/${versionOfClientB.id}`)
// after
const versions = await fetch(`/api/mcp-clients/${versionOfClientB.mcpClientId}/versions`).then(r => r.json());
fetch(`/api/mcp-clients/${versionOfClientB.mcpClientId}/versions/${versionOfClientB.id}`)
Defensive patterns

Strategy: validation

Validate before calling

const version = await getVersionSomewhere(versionId);
if (version && version.mcpClientId !== clientId) {
  throw new Error(`Version ${versionId} belongs to client ${version.mcpClientId}, not ${clientId}`);
}

Type guard

function belongsToClient(version: { mcpClientId: string } | null, clientId: string): version is { mcpClientId: string } {
  return version !== null && version.mcpClientId === clientId;
}

Try / catch

try {
  const res = await fetch(`/api/mcp-clients/${clientId}/versions/${versionId}`);
  if (res.status === 404 && (await res.json()).message.includes('not found for MCP client')) {
    // id mismatch: rebuild URL from version.mcpClientId
  }
} catch (err) {
  // generic handling
}

Prevention

When it happens

Trigger: Calling the get-version endpoint with a valid versionId that belongs to a different MCP client than the one in the URL path.

Common situations: Mixing ids between two MCP clients when constructing the URL; caching a (clientId, versionId) pair where one half was later updated; copying an example URL and replacing only one id.

Related errors


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