You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Feature request: per-async-context current working directory
Problem
process.chdir() mutates the process-global current working directory. In a single-threaded event loop, multiple async functions interleave at await points and share that one global cwd, so a chdir() inside one task silently changes relative-path resolution for every other concurrently running task:
fs operations with relative paths
require.resolve() / ESM resolution
child_process spawn without an explicit cwd
anything else that resolves relative to process.cwd()
The conventional try/finally "push/pop" pattern is therefore not safe under concurrency: between chdir(newDir) and the finally { chdir(oldDir) }, any interleaved async task observes a cwd it did not set.
AsyncLocalStorage provides per-async-context state, but process.cwd() / process.chdir() are not ALS-aware, and no built-in mechanism exists for a working directory scoped to an async context (or to a single call).
Suggested directions
Make process.cwd() / process.chdir() respect an AsyncLocalStorage-provided override, e.g. process.chdir inside a scoped context only affects that context.
Alternatively, add an explicit scoped-run API, e.g. als.run({ cwd: '/foo' }, () => ...) where relative path resolution inside the callback uses /foo while the process cwd stays untouched.
At minimum, document in the process.chdir() / fs docs that chdir is process-global and not safe to use across interleaved async operations, since many users assume per-call isolation.
This mirrors thread-local cwd support found in other runtimes and would unblock use cases like per-request build tools, sandboxing, and test runners that currently must spawn child processes (or re-implement path resolution) just to get an isolated working directory.
Feature request: per-async-context current working directory
Problem
process.chdir()mutates the process-global current working directory. In a single-threaded event loop, multiple async functions interleave atawaitpoints and share that one global cwd, so achdir()inside one task silently changes relative-path resolution for every other concurrently running task:fsoperations with relative pathsrequire.resolve()/ ESM resolutionchild_processspawn without an explicitcwdprocess.cwd()The conventional try/finally "push/pop" pattern is therefore not safe under concurrency: between
chdir(newDir)and thefinally { chdir(oldDir) }, any interleaved async task observes a cwd it did not set.AsyncLocalStorageprovides per-async-context state, butprocess.cwd()/process.chdir()are not ALS-aware, and no built-in mechanism exists for a working directory scoped to an async context (or to a single call).Suggested directions
process.cwd()/process.chdir()respect anAsyncLocalStorage-provided override, e.g.process.chdirinside a scoped context only affects that context.als.run({ cwd: '/foo' }, () => ...)where relative path resolution inside the callback uses/foowhile the process cwd stays untouched.process.chdir()/fsdocs that chdir is process-global and not safe to use across interleaved async operations, since many users assume per-call isolation.This mirrors thread-local cwd support found in other runtimes and would unblock use cases like per-request build tools, sandboxing, and test runners that currently must spawn child processes (or re-implement path resolution) just to get an isolated working directory.
Related
process.chdirin worker thread #41673 ("Supportprocess.chdirin worker thread", closed) — previously discussed isolating cwd per worker.fsAPIs already accept an explicitcwdoption, but that does not coverprocess.chdir-style global relative resolution.Node.js version: current stable (reproducible on any recent version).