Repository navigation
[v2] Test suite fails on Windows: 3 independent causes (CRLF checkout, symlink EPERM, POSIX signals) #3117
Description
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):
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:
- Add a
.gitattributesthat keeps the twins as LF (e.g.packages/core-internal/test/corpus/schema-twins/* -text). Or a repo-wide* text=auto eol=lfif you prefer. - Use
'junction'instead of'dir'onwin32in that test. Junctions don't need privileges and still form the cycle, so the test keeps covering Windows. - Skip the shutdown-escalation scenario on
win32, or on Windows only assert that the child is dead afterclose().
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 testSDK 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
DoroteoNavarrete commentedon Oct 27, 2026
One more data point for the
.gitattributeschoice:pnpm lint:allalso fails on Windows for the same reason. Withcore.autocrlf=trueevery file is checked out with CRLF, and Prettier's defaultendOfLine: "lf"flags all of them (61 files inpackages/codemodalone, including untouched ones).prettier --check --end-of-line auto .passes, so it's only line endings.A repo-wide
* text=auto eol=lfwould fix both this and the schema twins, so it's probably the better of the two options I listed.wozhenbang2004 commentedon Oct 29, 2026
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
-textattribute under a freshcore.autocrlf=truecheckout. 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.