Skip to content

fix: prevent rpc timeout on slow thread blocking synchronous methods#8297

Merged
sheremet-va merged 4 commits into
vitest-dev:mainfrom
AriPerkkio:fix/rpc-timeout-ignore
Jul 22, 2025
Merged

fix: prevent rpc timeout on slow thread blocking synchronous methods#8297
sheremet-va merged 4 commits into
vitest-dev:mainfrom
AriPerkkio:fix/rpc-timeout-ignore

Conversation

@AriPerkkio

@AriPerkkio AriPerkkio commented Jul 13, 2025

Copy link
Copy Markdown
Member

Description

Ref:

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. If the feature is substantial or introduces breaking changes without a discussion, PR might be closed.
  • Ideally, include a test that fails without this PR but passes with it.
  • Please, don't make changes to pnpm-lock.yaml unless you introduce a new test example.

Tests

  • Run the tests with pnpm test:ci.

Documentation

  • If you introduce new functionality, document it. You can run documentation with pnpm run docs command.

Changesets

  • Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with feat:, fix:, perf:, docs:, or chore:.

Comment thread packages/vitest/src/api/setup.ts
@netlify

netlify Bot commented Jul 13, 2025

Copy link
Copy Markdown

Deploy Preview for vitest-dev ready!

Name Link
🔨 Latest commit bbb7b9a
🔍 Latest deploy log https://app.netlify.com/projects/vitest-dev/deploys/687f936c578ee500084e97d4
😎 Deploy Preview https://deploy-preview-8297--vitest-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment thread packages/vitest/src/runtime/worker.ts
@AriPerkkio

AriPerkkio commented Jul 13, 2025

Copy link
Copy Markdown
Member Author

Worker side error can be tested locally with following changes:

Details
diff --git a/packages/vitest/src/node/pools/rpc.ts b/packages/vitest/src/node/pools/rpc.ts
index 351043ad2..7d69b3bb3 100644
--- a/packages/vitest/src/node/pools/rpc.ts
+++ b/packages/vitest/src/node/pools/rpc.ts
@@ -92,6 +92,9 @@ export function createMethodsRPC(project: TestProject, options: MethodsOptions =
     async onTaskAnnotate(testId, annotation) {
       return ctx._testRun.annotate(testId, annotation)
     },
+    async exampleMethodThatsStuck() {
+      await new Promise((resolve) => {})
+    },
     async onTaskUpdate(packs, events) {
       if (options.collect) {
         ctx.state.updateTasks(packs)
diff --git a/packages/vitest/src/runtime/runners/index.ts b/packages/vitest/src/runtime/runners/index.ts
index 26d91a2a2..d5ef6f1c9 100644
--- a/packages/vitest/src/runtime/runners/index.ts
+++ b/packages/vitest/src/runtime/runners/index.ts
@@ -101,6 +101,7 @@ export async function resolveTestRunner(
   testRunner.onAfterRunFiles = async (files) => {
     const state = getWorkerState()
     const coverage = await takeCoverageInsideWorker(config.coverage, executor)
+    rpc().exampleMethodThatsStuck()
 
     if (coverage) {
       rpc().onAfterSuiteRun({
diff --git a/packages/vitest/src/types/rpc.ts b/packages/vitest/src/types/rpc.ts
index f6fd773e8..dc5447322 100644
--- a/packages/vitest/src/types/rpc.ts
+++ b/packages/vitest/src/types/rpc.ts
@@ -32,6 +32,8 @@ export interface RuntimeRPC {
   onCancel: (reason: CancelReason) => void
   getCountOfFailedTests: () => number
 
+  exampleMethodThatsStuck: () => void
+
   snapshotSaved: (snapshot: SnapshotResult) => void
   resolveSnapshotPath: (testPath: string) => string
 }
 RUN  v4.0.0-beta.2 /x/examples/packages/vitest-example

 ✓ test/add.test.ts (1 test) 1ms
   ✓ example 0ms
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Rejection ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Error: [vitest-worker]: Closing rpc while "exampleMethodThatsStuck" was pending
 ❯ ../../../vitest/packages/vitest/src/runtime/worker.ts:79:16
 ❯ ../../../birpc/dist/index.mjs:97:27
 ❯ Proxy.rejectPendingCalls ../../../birpc/dist/index.mjs:96:19
 ❯ ../../../vitest/packages/vitest/src/runtime/worker.ts:78:29
 ❯ ../../../vitest/packages/vitest/src/runtime/worker.ts:120:42
 ❯ execute ../../../vitest/packages/vitest/src/runtime/worker.ts:120:32
 ❯ onMessage ../../../vitest/node_modules/.pnpm/[email protected]/node_modules/tinypool/dist/entry/process.js:39:18

This error originated in "test/add.test.ts" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
This error was caught after test environment was torn down. Make sure to cancel any running tasks before test finishes:
- cancel timeouts using clearTimeout and clearInterval
- wait for promises to resolve using the await keyword
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯


 Test Files  1 passed (1)
      Tests  1 passed (1)
     Errors  1 error
   Start at  09:55:52
   Duration  200ms (transform 15ms, setup 0ms, collect 15ms, tests 1ms, environment 0ms, prepare 36ms)

@AriPerkkio
AriPerkkio force-pushed the fix/rpc-timeout-ignore branch from d232fee to 935a6ea Compare July 14, 2025 17:21
@AriPerkkio
AriPerkkio marked this pull request as ready for review July 14, 2025 17:31
@sheremet-va
sheremet-va merged commit bea8746 into vitest-dev:main Jul 22, 2025
21 of 24 checks passed
@AriPerkkio
AriPerkkio deleted the fix/rpc-timeout-ignore branch July 22, 2025 19:37
@mcavigelli

Copy link
Copy Markdown

We have similar issues as Azure/typespec-azure#3169 on docker / Linux.

The failure is very difficult to find as the test name does not appear in the error message.
It would be nice to have a release with this fixed bug and merged pull request.

@AriPerkkio

Copy link
Copy Markdown
Member Author

The failure is very difficult to find as the test name does not appear in the error message. It would be nice to have a release with this fixed bug and merged pull request.

https://github.com/vitest-dev/vitest/releases/tag/v4.0.0-beta.4

@mcavigelli

Copy link
Copy Markdown

Thank you, that seems to work.

jpr5 added a commit to CopilotKit/CopilotKit that referenced this pull request Apr 19, 2026
…ate timeout (#4087)

## Problem

`showcase/scripts` test runs intermittently fail with birpc
`onTaskUpdate` timeouts, caused by an upstream bug in vitest 3.x's
subprocess reporter transport
([vitest-dev/vitest#8164](vitest-dev/vitest#8164)).
Fix landed upstream in
[#8297](vitest-dev/vitest#8297), shipped in
v4.0.0-beta.4+.

## Why this is safe

- **Blast radius is this one package.** Root `package.json` already
declares `"vitest": "^4.1.3"`. The only holdout was
`showcase/scripts/package.json` at `"vitest": "^3.0.0"`. All 10
subprocess-spawning test files in the monorepo live in
`showcase/scripts/__tests__/` — zero elsewhere — so this is the only
package actually affected by the bug.
- **Zero vitest API breaks in the diff.** Spot-checked: no `vi.mock`, no
`expect.extend`, no `.concurrent`, no snapshots, no coverage config, no
custom reporters. Only `vi.spyOn` (unchanged in v4) and standard
`describe`/`it`/`expect`.
- **Pool config unchanged.** `pool: 'forks'` + `fileParallelism` behave
identically in v3 and v4.
- **Lockfile diff is minimal.** Only `showcase/scripts` import
resolution changes + a new `@vitest/[email protected]` snapshot. No other
package was edited; no other package's resolution changed. vitest 3.2.4
and 2.1.9 continue to resolve side-by-side for the packages that still
pin them.

## Verification

3 consecutive `pnpm nx run @copilotkit/showcase-scripts:test
--skip-nx-cache` runs on Node 20.20.2:

| Run | Result | Wall time | Tests |
|-----|--------|-----------|-------|
| 1 | green | 34.45s | 1061/1061 |
| 2 | green | 29.64s | 1061/1061 |
| 3 | green | 29.46s | 1061/1061 |

Zero `onTaskUpdate` errors, zero unhandled exceptions across all three
runs.

## Test plan

- [ ] CI unit(20.x) green — this has been the red one on recent PRs due
to this exact bug
- [ ] CI unit(22.x) green
- [ ] CI unit(24.x) green

## Relationship to #4081

Complementary, not overlapping. #4081 splits / isolates the
showcase-scripts test suite as a workaround at the Nx/pool-config layer.
This PR fixes the root cause in the test runner itself. Once this
merges, the `onTaskUpdate` failures #4081 has been chasing should clear;
#4081 can then rebase on a clean main and its remaining work (the
split/isolation improvements) can be evaluated on its own merits rather
than as a bug workaround.
chainlesschain pushed a commit to chainlesschain/chainlesschain that referenced this pull request May 5, 2026
Vitest 4 lets us drop the workarounds that gated #5 (Windows continue-
on-error) and #4 (poolMatchGlobs federation override): birpc now
respects user-configured timeouts (vitest-dev/vitest#8297), the legacy
basic reporter is replaced by default+silent=passed-only.

Also bump @vitejs/plugin-vue 5.x → 6.0.6 in web-panel and desktop-app-
vue: vitest 4's vite peer requires vite ^6 || ^7 || ^8, plugin-vue 5
caps at vite ^6, conflict surfaces as ERESOLVE on web-panel install.

Affected: cli, web-panel, core-mtc, session-core, shared-logger,
core-{db,env,infra,config}, desktop-app-vue (incl. @vitest/coverage-v8
and @vitest/ui).
chainlesschain pushed a commit to chainlesschain/chainlesschain that referenced this pull request May 5, 2026
Vitest 4 removed test.poolOptions; forks/threads/etc are now top-level.
Also drop poolMatchGlobs from packages/cli/vitest.config.js — it routed
mtc-federation-governance-*-cli files to the threads pool to dodge
v3's hardcoded 60s birpc onTaskUpdate heartbeat (issue #4). Vitest 4
fixes the underlying RPC bug (vitest-dev/vitest#8297, shipped v4.0.0),
so the workaround is no longer needed; the file split done in
0114aec stays.
ryansolid added a commit to solidjs/solid that referenced this pull request May 11, 2026
The "Unhandled Error: [vitest-worker]: Timeout calling onTaskUpdate" we
were seeing in CodSpeed CI is a known vitest 3.x bug
(vitest-dev/vitest#8164) where birpc's hardcoded 60s RPC timeout fires
when the worker thread is blocked by slow synchronous code — exactly
what happens under CodSpeed's Valgrind instrumentation.

The fix shipped in vitest 4.0.0-beta.4 (vitest-dev/vitest#8297) and is
now in stable 4.1.6. CodSpeed's vitest plugin already supports vitest 4
(peer: ^3.2 || ^4), and our existing Vite 7 + Node 20+ stack meets
v4's prerequisites.

Now that the RPC timeout is solved at the source, the bench-only
forks/singleFork/inflated-timeout workaround we added in eb902be is no
longer needed; reverted those vite.config tweaks to keep the configs
small and uniform across test and bench runs.

Also widens tooling tsconfig types so bench files can read process.env
(needed by the CodSpeed env guard in update-partial.bench.tsx, which
was already there but was previously masked).

Co-authored-by: Cursor <[email protected]>
tyleretters added a commit to northern-information/revery-prairie that referenced this pull request May 21, 2026
CI flaked sporadically on test-engine with the unhandled error
`[vitest-worker]: Timeout calling "onTaskUpdate"`, even though every
test passed. Three prior deflake attempts (commits 884df74, 3e1a34a,
8dcd25f) addressed surrounding pressure but couldn't fix the root cause:
vitest 3.x's birpc dependency had a hardcoded 60-second DEFAULT_TIMEOUT
on inter-process RPC calls. Under CI load, an `onTaskUpdate` heartbeat
from a worker fork could land past 60s while the main reporter was
busy, and the stale promise would then reject right at teardown.

vitest 4 (PR vitest-dev/vitest#8297, shipped in 4.1.6) sets
`timeout: -1` on createBirpc — no heartbeat timeout. The flake is
structurally impossible on 4.1.7. Verified locally: 171/171 test files,
2926/2926 tests, no unhandled error.

Migration:
 - vitest.config.ts: `poolOptions.forks.maxForks` → top-level
   `maxWorkers`, drop the no-longer-relevant `minForks`. Comment
   updated to reflect the new root-cause understanding.
 - tsconfig.app.json: add `"node"` to types. Vitest 4 stopped pulling
   `@types/node` in transitively, so a couple of src/harness/__tests__
   files using `__dirname` / bare `'fs'` imports started failing
   typecheck. Adding node explicitly is the right fix.
 - src/hooks/__tests__/useInventoryDrag.test.ts +
   src/hooks/__tests__/useKeyboard.test.ts: `ReturnType<typeof vi.fn>`
   typed as `Mock<Procedure | Constructable>` in vitest 4 (vs the more
   permissive vitest 3 type), so it no longer assigns to a `() => void`
   parameter. Switched to the more specific `MockedFunction<() => void>`.

Side benefit: a future *real* RPC hang now never surfaces via the 60s
timer — it surfaces only via teardownTimeout (60s) or testTimeout (30s),
which is fine. We were already past the 60s window in CI and the
hardcoded value was hiding genuinely-fast tests behind a flaky failure
mode.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Skip-Harness: tooling change — vitest dependency upgrade only, no product code touched
chetwerikoff added a commit to chetwerikoff/orchestrator-pack that referenced this pull request Jul 8, 2026
Vitest 3.x birpc caps worker RPC at 60s while subprocess-heavy tests use
120–180s testTimeout; long spawnSync blocks trigger false onTaskUpdate
timeouts in CI even with per-file threads. Vitest 4 aligns RPC with test
timeouts (vitest-dev/vitest#8297).

Co-authored-by: Cursor <[email protected]>
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.

testTimeout is not fully respected: Error: [vitest-worker]: Timeout calling "onTaskUpdate"

3 participants