Skip to content

[v2] Test suite fails on Windows: 3 independent causes (CRLF checkout, symlink EPERM, POSIX signals) #3117

Open

Description

@DoroteoNavarrete

What happened?

Running pnpm -r test on a fresh clone of main (39ae8e6) on Windows gives 5 failures in 3 packages. Build passes and everything else is green. CI only runs on ubuntu-latest, so this doesn't show up there.

Each failure has a different cause:

1. core-internal — schema twin byte-identity (2 tests)
test/wire/schemaTwinConformance.test.ts

AssertionError: byte size drifted for 2025-11-25 — the vendored twin was rewritten: expected 178384 to be 174326

The repo has no .gitattributes, and Git for Windows defaults to core.autocrlf=true, so the twins are checked out with CRLF. 2025-11-25.schema.json has 4058 lines and is exactly 4058 bytes larger than the committed file. Same for 2026-07-28 (185437 vs 181474).

Screenshot of the core-internal run (both twins fail):

core-internal schemaTwinConformance test failing on Windows

2. codemod — symlink cycle test (1 test)
test/v1-to-v2/packageJsonUpdater.test.ts > "survives a directory symlink cycle without following it"

Error: EPERM: operation not permitted, symlink '...\codemod-manifests-DQY0E9' -> '...\codemod-manifests-DQY0E9\src\loop'

Creating a directory symlink on Windows needs admin rights or Developer Mode, so the test fails during setup, before the codemod runs.

3. test/e2e — transport:stdio:shutdown-escalation (2 tests)
scenarios/stdio.test.ts:208

AssertionError: expected '[stdio-server] ready\n' to contain '[stdio-server] sigterm ignored'

On Windows there are no POSIX signals: per the Node docs, subprocess.kill('SIGTERM') means the process "will always be killed forcefully and abruptly (similar to 'SIGKILL')". So the fixture can never ignore SIGTERM. The transport itself works (the child does die); it's the test's premise that doesn't hold on Windows.


Possible fixes, happy to send them as PRs if this sounds right:

  1. Add a .gitattributes that keeps the twins as LF (e.g. packages/core-internal/test/corpus/schema-twins/* -text). Or a repo-wide * text=auto eol=lf if you prefer.
  2. Use 'junction' instead of 'dir' on win32 in that test. Junctions don't need privileges and still form the cycle, so the test keeps covering Windows.
  3. Skip the shutdown-escalation scenario on win32, or on Windows only assert that the child is dead after close().

Would you prefer one PR or three separate ones? Separately, would adding a windows-latest job to the test matrix be welcome?

What did you expect?

The suite to pass on Windows, or the Windows-only cases to be skipped explicitly.

Code to reproduce

git clone https://github.com/modelcontextprotocol/typescript-sdk.git
cd typescript-sdk
pnpm install --frozen-lockfile
pnpm build:all
pnpm --filter @modelcontextprotocol/core-internal test
pnpm --filter @modelcontextprotocol/codemod test
pnpm --filter @modelcontextprotocol/test-e2e test

SDK version

main @ 39ae8e6 (2026-10-27) — Windows 11 Pro 26100, Node 24.11.1, pnpm 10.26.1, git 2.52.0.windows.1 (core.autocrlf=true)

Area

Other

Activity

  1. added
    v2Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes
    on Oct 27, 2026
  2. DoroteoNavarrete commented on Oct 27, 2026

    @DoroteoNavarrete
    Author

    One more data point for the .gitattributes choice: pnpm lint:all also fails on Windows for the same reason. With core.autocrlf=true every file is checked out with CRLF, and Prettier's default endOfLine: "lf" flags all of them (61 files in packages/codemod alone, including untouched ones). prettier --check --end-of-line auto . passes, so it's only line endings.

    A repo-wide * text=auto eol=lf would fix both this and the schema twins, so it's probably the better of the two options I listed.

  3. wozhenbang2004 commented on Oct 29, 2026

    @wozhenbang2004

    I’ll investigate the schema-twin byte-integrity failure as a small, separate fix. The existing manifest intentionally hashes the upstream bytes, so I’ll test a targeted -text attribute under a fresh core.autocrlf=true checkout. The symlink and signal cases can remain separate. I’m using Codex assistance and will report exactly which checks were run; I don’t have a native Windows environment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    v2Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions