Skip to content

fix(module): register server templates in a fixed order - #408

Merged
HugoRCD merged 1 commit into
nuxt-modules:mainfrom
onmax:fix/stable-virtual-template-order
Nov 2, 2026
Merged

HugoRCD merged 1 commit into
nuxt-modules:mainfrom
onmax:fix/stable-virtual-template-order

Conversation

@onmax

@onmax onmax commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Problem

With many layers, the key order of nuxt.options.nitro.virtual changes between identical builds. The output is the same, but a hash of the Nitro config (for example, a build cache key) changes on each build.

loadAllDefinitions runs five loaders with Promise.all. Each loader calls addServerTemplate when its scan finishes, so the keys are added in the order the scans finish.

Repro

The app extends 20 layers. Each layer has one tool, one prompt and one resource in server/mcp/. This script loads the app 10 times and shows the keys:

// node print-order.mjs <app-dir>
import { loadNuxt } from '@nuxt/kit'

for (let i = 1; i <= 10; i++) {
  const nuxt = await loadNuxt({ cwd: process.argv[2], dev: false, ready: true })
  console.log(Object.keys(nuxt.options.nitro.virtual ?? {})
    .filter(key => key.startsWith('#nuxt-mcp-toolkit/')).join(' '))
  await nuxt.close()
}

Before the fix, there are 7 different orders in 10 runs (prefix removed):

config transport handlers default-handler resources prompts tools
config transport handlers default-handler tools prompts resources
config transport handlers default-handler resources prompts tools
config transport default-handler handlers prompts tools resources
config transport handlers default-handler resources tools prompts
config transport handlers default-handler resources tools prompts
config transport handlers default-handler prompts tools resources
config transport default-handler handlers prompts resources tools
config transport default-handler prompts tools resources handlers
config transport default-handler handlers prompts tools resources

After the fix, all 10 runs give the same order:

config transport tools resources prompts handlers default-handler

Fix

The scans still run in parallel. Each loader now returns its template and does not register it. After Promise.all is complete, loadAllDefinitions registers the five templates in this order: tools, resources, prompts, handlers, default handler. The template contents do not change.

test/loaders-order.test.ts makes the scan of one definition type slow, then checks the order. Before the fix, all 3 cases fail.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

@onmax is attempting to deploy a commit to the Nuxt Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added the bug Something isn't working label Oct 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thank you for following the naming conventions! 🙏

@pkg-pr-new

pkg-pr-new Bot commented Oct 31, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/nitro-mcp-toolkit@408
npm i https://pkg.pr.new/@nuxtjs/mcp-toolkit@408

commit: 3bfbe55

@HugoRCD
HugoRCD merged commit c4f0414 into nuxt-modules:main Nov 2, 2026
16 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants