Skip to content

fix(run-multiple): avoid temp.mjs filename collision across forked processes#5644

Closed
kapil971390 wants to merge 1 commit into
codeceptjs:4.xfrom
kapil971390:fix/run-multiple-temp-mjs-race
Closed

fix(run-multiple): avoid temp.mjs filename collision across forked processes#5644
kapil971390 wants to merge 1 commit into
codeceptjs:4.xfrom
kapil971390:fix/run-multiple-temp-mjs-race

Conversation

@kapil971390

Copy link
Copy Markdown
Contributor

Problem

Fixes #5642

When run-multiple launches N concurrent worker processes, each process independently transpiles the same TypeScript files (config, helpers, page objects, includes) to temporary .temp.mjs files. Since the temp filename is derived purely from the source path:

// before
const tempFile = filePath.replace(/\.ts$/, '.temp.mjs')

all workers write to the same path (e.g. CustomHelper.temp.mjs). When one worker finishes and deletes its temp file via cleanupTempFiles(), any other worker that hasn't yet import()ed the file fails with:

Error: Cannot find module '.../CustomHelper.temp.mjs'

This is a classic TOCTOU race; the repro in #5642 shows it failing ~85% of the time with 12 workers.

Fix

Embed process.pid in the temp filename so each worker writes its own isolated copy:

// after
const tempFile = filePath.replace(/\.ts$/, `.${process.pid}.temp.mjs`)

No other changes needed:

  • cleanupTempFiles() iterates allTempFiles which is built from transpiledFiles.values() — already contains the pid-suffixed paths, so cleanup is correct.
  • lib/step/base.js uses .includes('.temp.mjs') (substring), which matches *.{pid}.temp.mjs unchanged.

Test plan

…ocesses

When run-multiple forks N concurrent processes, each process transpiles the
same .ts files (config, helpers, includes) to identically named *.temp.mjs
files. A process that finishes first deletes its temp file, causing other
processes that haven't imported it yet to fail with "Cannot find module
*.temp.mjs".

Fix: embed process.pid in the temp filename so every worker writes its own
isolated copy. Cleanup still works because allTempFiles is built from
transpiledFiles.values(), which already contains the pid-suffixed paths.
The .includes('.temp.mjs') substring check in step/base.js continues to
match the new *.{pid}.temp.mjs filenames.

Fixes codeceptjs#5642
@kapil971390

Copy link
Copy Markdown
Contributor Author

Closing as duplicate of #5643 by @mirao which fixes the same race condition. Great minds!

@DavertMik

Copy link
Copy Markdown
Contributor

Indeed. That's great!

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.

4.x: The test in the mode "run-multiple" sometimes fails: "Cannot find module *.temp.mjs"

3 participants