Skip to content

chore(deps): hold msw at 2.x on the @vitest/mocker peer range - #428

Merged
saquibrashid merged 1 commit into
mainfrom
chore/hold-msw-3
Oct 8, 2026
Merged

saquibrashid merged 1 commit into
mainfrom
chore/hold-msw-3

Conversation

@saquibrashid

Copy link
Copy Markdown
Owner

Summary

msw 3 cannot be installed in this repo, and the error does not say so.
Every one of the twelve jobs on #424 died inside 15 seconds at npm ci:

npm error code EUSAGE
npm error Missing: msw@2.15.0 from lock file
npm error Missing: @mswjs/interceptors@0.41.9 from lock file   (+ ~25 more)

⚠ That reads like a stale lockfile and is not one. It survived two
@dependabot rebase rounds, a rerun --failed, and a close/reopen. The
lockfile on that branch is correct: node_modules/msw resolves 3.0.2, the
root manifest declares "msw": "3.0.2", and no manifest or lock entry
anywhere mentions 2.15.0.

The cause is an optional peer dependency we do not own. @vitest/mocker —
pulled in by vitest, and still at 5.0.3, the latest published version —
declares:

"peerDependencies":     { "msw": "^2.4.9" },
"peerDependenciesMeta": { "msw": { "optional": true } }

msw@3.0.2 does not satisfy ^2.4.9, so npm wants to nest an msw@2.15.0
beside the mocker. Dependabot's lockfile has no such nested entry, so the tree
npm computes and the tree the lockfile describes disagree → EUSAGE.

⚠ It only reproduces on CI's npm, which is the trap. npm ci --dry-run on
the exact merge commit CI rejected (2bed305) succeeds under local
npm 11.11.0, and fails with the identical error under npx npm@10.9.4 — which
is what Node 22.23.3 bundles in CI. "It installs fine locally" proves nothing
here.

A second, independent blocker sits behind the first. msw 3 moved its entry
points, so even once the peer range is fixed this is a migration, not a bump:
import { http, HttpResponse, passthrough } from 'msw' becomes 'msw/http',
and onUnhandledRequest becomes onUnhandledFrame. That touches the four
fixture servers in tests/fixtures/msw/* and the ~12 specs that start them. A
version-only Dependabot PR can never be green on its own.

This PR records both findings with a named exit criterion, in the same shape as
the jsdom hold that landed in #426.

Linked issue / task

Closes #424.

Type of change

  • Feature (a backlog task)
  • Bug fix
  • Refactor / internal
  • Docs / specs
  • Infrastructure (infra/**) — .github/dependabot.yml

Testing done

Documentation and Dependabot configuration only; no acceptance criterion
changes, so no AC → test mapping applies (specs/testing.md §10).

Gates run locally on this branch:

Command Result
npm run format:check passed — "All matched files use Prettier code style!"
python -c "import yaml; ..." (parse .github/dependabot.yml) passed — ignore list parses to the 8 expected entries, msw >=3 among them

Evidence gathered while diagnosing (not gates):

Command Result
npm ci --dry-run on 2bed305 under npm 11.11.0 succeeded
npx -y npm@10.9.4 ci --dry-run on 2bed305 failed, EUSAGE … Missing: msw@2.15.0 — reproduces CI exactly
npm view "@vitest/mocker@latest" peerDependencies { msw: '^2.4.9', vite: '^6.0.0 || ^7.0.0 || ^8.0.0' }

T-INFRA-018d reads only package.json, .nvmrc and Dockerfile, so a new
dependabot.yml ignore entry does not affect it.

Checklist

  • Every acceptance criterion touched maps to a named test that passes. — none touched.
  • No new telemetry/analytics dependency (dependency allow-list, TASK-004). — no dependency change at all.
  • No secret, credential, connection string, blob URL or SAS in code, logs, or responses.
  • Any new runtime dependency is justified against NFR-004 in this description. — none added.
  • Migrations contain no destructive statement (T-MIG-001). — no migrations.
  • No scheduler / TTL / Agent-job / Elastic-job added (REQ-028, REQ-041).
  • If I edited an executable instruction in a doc, I corrected it in place and struck through the superseded text (the F-001 rule). — the runbook change is a new §5 entry; no existing instruction was superseded.

msw 3 cannot be installed here, and the error does not say so. Every job
on #424 died at `npm ci` with EUSAGE "Missing: msw@2.15.0 from lock file",
which reads like a stale lockfile and is not one: the branch lockfile
resolves msw@3.0.2 and nothing anywhere declares 2.15.0.

The cause is an optional peer dependency we do not own. @vitest/mocker,
pulled in by vitest and still at 5.0.3 (latest), declares an optional peer
`msw: ^2.4.9`. msw 3 does not satisfy it, so npm nests an msw@2.15.0 beside
the mocker - a tree Dependabot's lockfile does not describe.

It reproduces only on CI's npm. `npm ci --dry-run` on the exact merge commit
CI rejected succeeds under npm 11.11.0 and fails under npx npm@10.9.4, which
is what Node 22.23.3 bundles in CI.

A second independent blocker sits behind the first: msw 3 moved its entry
points, so `from 'msw'` becomes `from 'msw/http'` and `onUnhandledRequest`
becomes `onUnhandledFrame` across the four tests/fixtures/msw servers and
the ~12 specs that start them. A version-only bump can never be green.

Records both in .github/dependabot.yml and runbook section 5, with a named
exit criterion: @vitest/mocker widening its msw peer range.

Closes #424

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c372e6ba-4c3f-419a-9f77-b9e23adfc874
@saquibrashid
saquibrashid merged commit 7805b38 into main Oct 8, 2026
13 checks passed
@saquibrashid
saquibrashid deleted the chore/hold-msw-3 branch October 8, 2026 18:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant