Skip to content

http-server-csharp: npm install loads two incompatible @alloy-js/core versions ('Multiple versions of Alloy are loaded') #11443

Description

@timotheeguerin

Describe the bug

Compiling a project that uses @typespec/http-server-csharp with npm fails at load time:

error js-error: Failed to load .../node_modules/@typespec/http-server-csharp/dist/src/index.js due to the following JS error: Multiple versions of Alloy are loaded for this project. This will likely cause undesirable behavior.

Two incompatible versions of @alloy-js/core end up installed and both get loaded at runtime:

  • node_modules/@alloy-js/core0.24.1 (hoisted)
  • node_modules/@typespec/http-canonicalization/node_modules/@alloy-js/core0.22.0 (nested)

Root cause

@alloy-js/core is a peerDependency of @typespec/emitter-framework@0.17.0 with range ^0.22.0 (i.e. >=0.22.0 <0.23.0), which 0.24.1 does not satisfy.

The old emitter-framework@0.17 is dragged in transitively:

@typespec/http-server-csharp@0.58.0-alpha.30
  ├─ @alloy-js/core@^0.24.1                 → 0.24.1
  ├─ @typespec/emitter-framework@^0.19.0    → 0.19.0  (peer alloy ^0.24)
  └─ @typespec/http-canonicalization@^0.16.1 → 0.16.1
        └─ @typespec/emitter-framework@^0.17.0 → 0.17.0
              └─ peerDep @alloy-js/core @^0.22.0   ← forces a 2nd copy

npm 7+ auto-installs unmet peer dependencies, so it installs a second nested copy of @alloy-js/core@0.22.0 to satisfy the ^0.22.0 peer of emitter-framework@0.17. Both copies load and Alloy's runtime guard reports the conflict.

http-server-csharp effectively depends on two different major-ish lines of Alloy at once: 0.24 (directly and via emitter-framework@0.19) and 0.22 (via http-canonicalization@0.16.1emitter-framework@0.17).

Reproduction

package.json:

{
  "dependencies": {
    "@typespec/compiler": "^1.14.0",
    "@typespec/http": "^1.14.0",
    "@typespec/http-server-csharp": "^0.58.0-alpha.20"
  }
}
npm install
npx tsp compile .

Why it only fails with npm

  • npm: auto-installs the unmet ^0.22.0 peer → second Alloy copy → error.
  • pnpm: satisfies the peer with the single provided 0.24.1 (peer-range warning only) → one Alloy copy → works.
  • Workaround: forcing a single version via npm overrides also works:
    "overrides": { "@alloy-js/core": "0.24.1" }

Suggested fix

Bump @typespec/http-server-csharp's dependency on @typespec/http-canonicalization to a release that uses @typespec/emitter-framework@0.19 (Alloy 0.24), so a single Alloy line is required across the tree.

Environment

  • @typespec/compiler: 1.14.0
  • @typespec/http-server-csharp: 0.58.0-alpha.30
  • @typespec/http-canonicalization: 0.16.1 (pulls @typespec/emitter-framework@0.17.0)
  • @alloy-js/core: 0.24.1 (hoisted) + 0.22.0 (nested)
  • npm with Node.js v26.5.0

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions