From dcccdbd1481a313b5486e0d07c6f6f46a7388911 Mon Sep 17 00:00:00 2001 From: martmull Date: Thu, 9 Jul 2026 10:58:26 +0200 Subject: [PATCH] Fix flaky "read EINVAL" in integration tests: bump msw to 2.12.14 (#22702) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Context Part of a CI flakiness sweep. Integration shards are intermittently killed by an uncaught socket error that poisons a whole spec file (e.g. `sync-failure-lifecycle.integration-spec.ts`, 4 tests, on unrelated PR branches — example run 28940565117, shard 8): ``` Error: read EINVAL at MockHttpSocket.emit (@mswjs/interceptors/.../MockHttpSocket.ts:161) ``` # Root cause The integration setup routes **all** HTTP (including supertest/node-fetch calls to the in-process app) through msw's ClientRequest interceptor, with localhost passthrough. msw `2.12.7` pins `@mswjs/interceptors` `0.40.0`, where: - `passthrough()` aliases the real socket's libuv `_handle` onto the mock socket (two owners of one handle) and forwards the real socket's `error` events into `MockHttpSocket.emit`, - `destroy()` never destroys the passthrough socket, so it stays orphaned with its error-forwarding listener attached. When the server side closes such a connection later, a read on the stale shared handle yields `EINVAL`, forwarded into `emit()` with no request (and no error listener) attached → uncaught exception → jest kills the in-flight file. This is upstream [mswjs/interceptors#753](https://github.com/mswjs/interceptors/issues/753); the stack frames match line-for-line. # Fix Bump `msw` to **exactly `2.12.14`** in `twenty-server` and `twenty-front` (shared lock entry). msw 2.12.9+ requires interceptors `^0.41.2` → resolves 0.41.9, which ships [interceptors#755](https://github.com/mswjs/interceptors/pull/755): passthrough sockets get their listeners removed and are destroyed on close, severing the exact error path above. Notes from adversarial review: - Pinned exact (`2.12.14`, not `^`) because the caret would resolve to 2.15.0 today — a bigger jump than reviewed. - Compatibility checked: no deep imports of msw/interceptors anywhere; interceptors 0.41.x externals already covered by `transformIgnorePatterns`; `msw-storybook-addon@2.0.6` peer range satisfied; `mockServiceWorker.js` integrity checksum unchanged between 2.12.7 and 2.12.14; 0.41.7+ adds Node 24 compatibility (repo targets Node 24). - Residual risk disclosed: #753 is still open upstream and the `_handle` aliasing remains in 0.41.9 — this removes the observed orphaned-socket path, but keep an eye out for recurrence. Dependency-only change: 2 package.json lines + lockfile. --- _Generated by [Claude Code](https://claude.ai/code/session_01AtD2wWm3EthV6t3Hs31QyB)_ Review in cubic --- packages/twenty-front/package.json | 2 +- packages/twenty-server/package.json | 2 +- yarn.lock | 32 ++++++++++++++--------------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/twenty-front/package.json b/packages/twenty-front/package.json index 905be4c410..5923755afb 100644 --- a/packages/twenty-front/package.json +++ b/packages/twenty-front/package.json @@ -194,7 +194,7 @@ "monaco-editor": "0.52.2", "monaco-editor-auto-typings": "^0.4.5", "monaco-graphql": "1.8.0", - "msw": "^2.12.7", + "msw": "2.12.14", "msw-storybook-addon": "^2.0.6", "optionator": "^0.9.1", "oxlint": "^1.51.0", diff --git a/packages/twenty-server/package.json b/packages/twenty-server/package.json index 886e118ef6..3754f28895 100644 --- a/packages/twenty-server/package.json +++ b/packages/twenty-server/package.json @@ -221,7 +221,7 @@ "@types/uuid": "^9.0.2", "jest": "29.7.0", "jest-environment-node": "^29.4.1", - "msw": "^2.12.7", + "msw": "2.12.14", "node-fetch": "^2.7.0", "prettier": "^3.1.1", "rimraf": "^5.0.5", diff --git a/yarn.lock b/yarn.lock index 725a31cfd9..826171533e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11964,9 +11964,9 @@ __metadata: languageName: node linkType: hard -"@mswjs/interceptors@npm:^0.40.0": - version: 0.40.0 - resolution: "@mswjs/interceptors@npm:0.40.0" +"@mswjs/interceptors@npm:^0.41.2": + version: 0.41.9 + resolution: "@mswjs/interceptors@npm:0.41.9" dependencies: "@open-draft/deferred-promise": "npm:^2.2.0" "@open-draft/logger": "npm:^0.3.0" @@ -11974,7 +11974,7 @@ __metadata: is-node-process: "npm:^1.2.0" outvariant: "npm:^1.4.3" strict-event-emitter: "npm:^0.5.1" - checksum: 10c0/4500f17b65910b2633182fdb15a81ccb6ccd4488a8c45bc2f7acdaaff4621c3cce5362e6b59ddc4fa28d315d0efb0608fd1f0d536bc5345141f8ac03fd7fab22 + checksum: 10c0/2efff40877e07ce29846be76c2683177308a72a3ccfe4c096b496412a279acd92b5b9cdad40ad71c36b149a4a7d9e9b4e7d295893a8ba9661b43334f5784ecd8 languageName: node linkType: hard @@ -42304,12 +42304,12 @@ __metadata: languageName: node linkType: hard -"msw@npm:^2.12.7": - version: 2.12.7 - resolution: "msw@npm:2.12.7" +"msw@npm:2.12.14": + version: 2.12.14 + resolution: "msw@npm:2.12.14" dependencies: "@inquirer/confirm": "npm:^5.0.0" - "@mswjs/interceptors": "npm:^0.40.0" + "@mswjs/interceptors": "npm:^0.41.2" "@open-draft/deferred-promise": "npm:^2.2.0" "@types/statuses": "npm:^2.0.6" cookie: "npm:^1.0.2" @@ -42319,7 +42319,7 @@ __metadata: outvariant: "npm:^1.4.3" path-to-regexp: "npm:^6.3.0" picocolors: "npm:^1.1.1" - rettime: "npm:^0.7.0" + rettime: "npm:^0.10.1" statuses: "npm:^2.0.2" strict-event-emitter: "npm:^0.5.1" tough-cookie: "npm:^6.0.0" @@ -42333,7 +42333,7 @@ __metadata: optional: true bin: msw: cli/index.js - checksum: 10c0/e9100fe87dce5411d29392bba88ed1813acc6278991a3068c328ec671e5eb52d1e8ee451ee401c554eab08e04b78b84fcdf2c78f761287c6b43e844e91ce18dd + checksum: 10c0/73e2c08a74bac94036c75aa0340e48573a233d5060cb3098ead7ec0eaddaacef4de399b81e0e3f41ea73d5f92341adc9cf0ae908ad74583d294afa4667e7d277 languageName: node linkType: hard @@ -48523,10 +48523,10 @@ __metadata: languageName: node linkType: hard -"rettime@npm:^0.7.0": - version: 0.7.0 - resolution: "rettime@npm:0.7.0" - checksum: 10c0/1460539d49415c37e46884bf1db7a5da974b239c1bd6976e1cf076fad169067dc8f55cd2572aec504433162f3627b6d8123eea977d110476258045d620bd051b +"rettime@npm:^0.10.1": + version: 0.10.1 + resolution: "rettime@npm:0.10.1" + checksum: 10c0/94fb30cd13684386c70301c4cff4391bc0c6dc7aeac49364fdfeeaba167897bdb28a58bbb46d1a415f1c5c6240fda3f765cb329e471f37fdc513c739f0b04fbe languageName: node linkType: hard @@ -52983,7 +52983,7 @@ __metadata: monaco-editor: "npm:0.52.2" monaco-editor-auto-typings: "npm:^0.4.5" monaco-graphql: "npm:1.8.0" - msw: "npm:^2.12.7" + msw: "npm:2.12.14" msw-storybook-addon: "npm:^2.0.6" optionator: "npm:^0.9.1" oxlint: "npm:^1.51.0" @@ -53261,7 +53261,7 @@ __metadata: microdiff: "npm:1.4.0" mrmime: "npm:^2.0.1" ms: "npm:2.1.3" - msw: "npm:^2.12.7" + msw: "npm:2.12.14" nest-commander: "npm:^3.19.1" node-fetch: "npm:^2.7.0" node-ical: "npm:^0.21.0"