Skip to content

Feature request: per-async-context current working directory (AsyncLocalStorage-aware chdir/cwd) #65784

Description

@steve02081504

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

  1. Make process.cwd() / process.chdir() respect an AsyncLocalStorage-provided override, e.g. process.chdir inside a scoped context only affects that context.
  2. 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.
  3. 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.

Related

  • Support process.chdir in worker thread #41673 ("Support process.chdir in worker thread", closed) — previously discussed isolating cwd per worker.
  • fs APIs already accept an explicit cwd option, but that does not cover process.chdir-style global relative resolution.

Node.js version: current stable (reproducible on any recent version).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions