Workers SDK Issue Reports

← Back to Dashboard

#11022 test setup crashes when running all tests after subset

Recommendation:KEEP OPEN
Difficulty:easy
Reasoning:

Bug confirmed in code: when rerunning all tests after running subset, Map<file, Miniflare> missing entries for newly discovered files causing assertion failure.

Suggested Action:

Fix getProjectMiniflare() to create Miniflare instances for newly discovered test files when reusing existing Map.

Analysis Report

Issue Review: cloudflare/workers-sdk#11022

Summary

vitest-pool-workers crashes with assertion error when running all tests after first running a subset, due to Miniflare instances not being created for newly discovered test files.

Findings

  • Created: 2025-10-20
  • Updated: 2025-10-20
  • Version: Not specified (vitest-pool-workers implied)
  • Component: vitest-pool-workers
  • Labels: bug
  • Comments: 0

Key Evidence

  1. Related issue #5942 (similar VSCode-triggered bug) is still OPEN
  2. No PRs found that fix either #11022 or #5942
  3. Neither issue mentioned in vitest-pool-workers CHANGELOG
  4. Bug is reproducible based on code analysis (see root cause below)

Root Cause Analysis

The bug occurs in packages/vitest-pool-workers/src/pool/index.ts in the runWorkersPool function.

The Problem:

When using isolated storage (isolatedStorage: true) without singleWorker, the pool creates a Map<string, Miniflare> where keys are test file paths. The issue is a race condition between test file discovery and Miniflare instance creation:

  1. Initial subset run (e.g., npm run test -- test/foo.spec.ts):

    • project.testFiles is populated with only test/foo.spec.ts
    • getProjectMiniflare() creates project.mf = new Map() with only one entry for foo.spec.ts (line 801)
  2. Re-run all tests (pressing a):

    • project.testFiles gets updated with ALL test files (line 1111)
    • BUT getProjectMiniflare() at line 778-780 checks project.mf !== undefined and since options haven't changed, it just logs "Reusing runtime..." and returns the existing Map
    • The existing Map only has entries for the original subset of files
    • When the code iterates over files (all test files) at line 1197, it tries to mf.get(file) for files that were never added to the Map
    • Assertion fails at line 1199: assert(fileMf !== undefined)

Code Reference:

// packages/vitest-pool-workers/src/pool/index.ts:796-804
if (singleInstance) {
  // ...
} else {
  log.info(`Starting isolated runtimes for ${project.relativePath}...`);
  project.mf = new Map();
  for (const testFile of project.testFiles) {  // <-- Only iterates current testFiles
    project.mf.set(testFile, new Miniflare(mfOptions));
  }
}
// packages/vitest-pool-workers/src/pool/index.ts:1196-1199
for (const file of files) {  // <-- files may include new test files
  const fileMf = mf.get(file);
  assert(fileMf !== undefined);  // <-- FAILS for new files not in Map

Proposed Solution

In getProjectMiniflare(), when reusing an existing Map of Miniflare instances, check if new test files have been added and create Miniflare instances for them:

// In getProjectMiniflare() around line 806, after the "Reusing runtime..." branch

} else if (project.mf instanceof Map) {
  // Check for new test files that don't have Miniflare instances yet
  const newFiles: string[] = [];
  for (const testFile of project.testFiles) {
    if (!project.mf.has(testFile)) {
      newFiles.push(testFile);
    }
  }
  if (newFiles.length > 0) {
    log.info(`Adding ${newFiles.length} new isolated runtime(s) for ${project.relativePath}...`);
    for (const testFile of newFiles) {
      project.mf.set(testFile, new Miniflare(mfOptions));
    }
    // Wait for new instances to be ready
    await Promise.all(newFiles.map(f => project.mf.get(f)!.ready));
  } else {
    log.debug(`Reusing runtime for ${project.relativePath}...`);
  }
} else {
  log.debug(`Reusing runtime for ${project.relativePath}...`);
}

Alternatively, a simpler fix at line 1196-1199 would be to create Miniflare instances on-demand:

for (const file of files) {
  let fileMf = mf.get(file);
  if (fileMf === undefined) {
    // Create Miniflare instance for newly discovered test file
    fileMf = new Miniflare(mfOptions);
    mf.set(file, fileMf);
    await fileMf.ready;
  }
  resultPromises.push(
    runTests(ctx, fileMf, name, project, config, [file], invalidates, method)
  );
}

Recommendation

Status: KEEP OPEN

Reasoning: The bug is confirmed to still exist in the current codebase. The root cause has been identified as a logic gap where Miniflare instances are not created for test files that are discovered after the initial run. The related issue #5942 is also still open, and no fixes have been merged.

Action: Fix the code in packages/vitest-pool-workers/src/pool/index.ts to handle newly discovered test files when reusing isolated Miniflare instances.

Implementation Details

  • Difficulty: Easy
  • Justification: Single file change, localized fix, clear logic gap
  • Files to modify: packages/vitest-pool-workers/src/pool/index.ts
  • Testing recommendations:
    1. Create a project with multiple test files and isolatedStorage: true
    2. Run a single test file: npm run test -- test/foo.spec.ts
    3. Press a to run all tests
    4. Verify all tests run without assertion error
    5. Add tests in the vitest-pool-workers test suite to cover this scenario

Notes & Feedback (0)

No notes yet.

Add Note