Skip to content

Some tests are not fully CWD-agnostic #61303

Description

@LiviaMedeiros

Version

v26.0.0-pre

Platform

Linux tumba 6.18.3-gentoo-yuran #1 SMP Sun Jan  4 21:50:21 +08 2026 x86_64 Intel(R) Core(TM)2 Quad CPU Q8200 @ 2.33GHz GenuineIntel GNU/Linux

Subsystem

test

What steps will reproduce the bug?

# cd /
# git clone --depth=1 https://github.com/nodejs/node.git
# cd node
# ./configure && make test-only

In realistic scenarios, cd / is implicit: for example, right after chroot or pivot_root into disposable environment.

How often does it reproduce? Is there a required condition?

Always.

What is the expected behavior? Why is that the expected behavior?

All tests are expected to pass.

What do you see instead?

A bunch of failing tests. Assertions are failing with something like:

+   '(node:*) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https:*js.org*api*cli.html#cli_unhandled_rejections_mode). (rejection id: 1)\n'
-   '(node:*) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https:*nodejs.org*api*cli.html#cli_unhandled_rejections_mode). (rejection id: 1)\n'
   'Error: an error!\n' +
+   '    at functionD (*/test/fixtures/source-map*_modules/error-stack/enclosing-call-site.js:16:17)\n' +
+   '    at functionC (*/test/fixtures/source-map*_modules/error-stack/enclosing-call-site.js:10:3)\n' +
+   '    at functionB (*/test/fixtures/source-map*_modules/error-stack/enclosing-call-site.js:6:3)\n' +
+   '    at functionA (*/test/fixtures/source-map*_modules/error-stack/enclosing-call-site.js:2:3)\n' +
+   '    at Object.<anonymous> (*/test/fixtures/source-map*_modules/error-stack/enclosing-call-site.js:24:3)\n' +
-   '    at functionD (*/test/fixtures/source-map/node_modules/error-stack/enclosing-call-site.js:16:17)\n' +
-   '    at functionC (*/test/fixtures/source-map/node_modules/error-stack/enclosing-call-site.js:10:3)\n' +
-   '    at functionB (*/test/fixtures/source-map/node_modules/error-stack/enclosing-call-site.js:6:3)\n' +
-   '    at functionA (*/test/fixtures/source-map/node_modules/error-stack/enclosing-call-site.js:2:3)\n' +
-   '    at Object.<anonymous> (*/test/fixtures/source-map/node_modules/error-stack/enclosing-call-site.js:24:3)\n' +
    'Error: an error!\n' +
+   '    at functionD (*/test/fixtures/source-map*_modules/error-stack/enclosing-call-site-min.js:1:156)\n' +
+   '    at functionC (*/test/fixtures/source-map*_modules/error-stack/enclosing-call-site-min.js:1:97)\n' +
+   '    at functionB (*/test/fixtures/source-map*_modules/error-stack/enclosing-call-site-min.js:1:60)\n' +
+   '    at functionA (*/test/fixtures/source-map*_modules/error-stack/enclosing-call-site-min.js:1:26)\n' +
+   '    at Object.<anonymous> (*/test/fixtures/source-map*_modules/error-stack/enclosing-call-site-min.js:1:199)\n'
-   '    at functionD (*/test/fixtures/source-map/node_modules/error-stack/enclosing-call-site-min.js:1:156)\n' +
-   '    at functionC (*/test/fixtures/source-map/node_modules/error-stack/enclosing-call-site-min.js:1:97)\n' +
-   '    at functionB (*/test/fixtures/source-map/node_modules/error-stack/enclosing-call-site-min.js:1:60)\n' +
-   '    at functionA (*/test/fixtures/source-map/node_modules/error-stack/enclosing-call-site-min.js:1:26)\n' +
-   '    at Object.<anonymous> (*/test/fixtures/source-map/node_modules/error-stack/enclosing-call-site-min.js:1:199)\n'

Additional information

The reason is that the tests simply remove matches to process.cwd(). In the examples above, CWD being /node corrupts http://nodejs.org and /node_modules.
Obviously there are other directories that may break tests, e.g. /test.

List of tests :

  • test/parallel/test-node-output-v8-warning.mjs
  • test/parallel/test-node-output-vm.mjs
  • test/parallel/test-node-output-console.mjs
  • test/parallel/test-node-output-sourcemaps.mjs
  • test/parallel/test-node-output-errors.mjs

Also the most edge case is CWD being /, assuming no conflict with /lib. In this case, additional failing tests are:

  • test/parallel/test-cli-permission-deny-fs.js - has skips if founds itself in /etc but doesn't check if it's even worse.
  • test/es-module/test-esm-import-meta.mjs - uses regexps that assume that leading / and /test... are not overlapped.

All of the above might be a valid good first issue Issues that are suitable for first-time contributors. material.


And then there are at least these tests in test-runner that validate test output, using common/assertSnapshot.js to normalize it:

  • test/test-runner/test-output-abort-runs-after-hook.mjs
  • test/test-runner/test-output-abort-hooks.mjs
  • test/test-runner/test-output-abort-suite.mjs
  • test/test-runner/test-output-abort.mjs
  • test/test-runner/test-output-filtered-suite-throws.mjs
  • test/test-runner/test-output-default-output.mjs
  • test/test-runner/test-output-global-after-should-fail-the-test.mjs
  • test/test-runner/test-output-source-mapped-locations.mjs
  • test/test-runner/test-output-describe-it.mjs
  • test/test-runner/test-output-test-runner-plan.mjs
  • test/test-runner/test-output-hooks.mjs
  • test/test-runner/test-output-test-timeout-flag.mjs
  • test/test-runner/test-output-output.mjs
  • test/test-runner/test-output-unfinished-suite-async-error.mjs
  • test/test-runner/test-output-test-timeout-flag-with-test.mjs
  • test/test-runner/test-output-timeout-in-before-each.mjs
  • test/test-runner/test-output-test-runner-plan-timeout.mjs
  • test/test-runner/test-output-lcov-reporter.mjs
  • test/test-runner/test-output-output-cli.mjs

Adjusting them individually would be an exercise in futility, so it's just an extra in case of bright ideas on making transformations from assertSnapshot more strict&robust and unify test-node-output-* as well.

Activity

  1. added
    testIssues and PRs related to Node.js core tests and test infrastructure.
    good first issueIssues that are suitable for first-time contributors.
    on Jan 7, 2026
  2. monam2 commented on Jan 7, 2026

    @monam2

    Hi! I'd like to try working on this issue, if that's okay.

  3. MikeMcC399 commented on Jan 7, 2026

    @MikeMcC399
    Contributor

    The Filesystem Hierarchy Standard (FHS) states in https://specifications.freedesktop.org/fhs/latest/rootFilesystem.html#rootPurpose

    Applications must never create or require special files or subdirectories in the root directory. Other locations in the FHS hierarchy provide more than enough flexibility for any package.

    so I'm not sure if it would be a valid repro scenario to be testing in the Linux root location /.

  4. gambare2 commented on Jan 9, 2026

    @gambare2

    Hi, I investigated this and it looks like the root problem is that test output normalization blindly removes process.cwd(), which causes unintended string corruption (e.g. /node stripping parts of nodejs.org).

    Would you be open to a small, scoped fix that only normalizes filesystem paths (instead of raw string replacement), possibly starting with test-node-output-* tests?

  5. LiviaMedeiros commented on Jan 10, 2026

    @LiviaMedeiros
    MemberAuthor

    @monam2 @gambare2 Sure!

    @MikeMcC399 The / is an edge case indicating that test is not fully agnostic. Depending on the exact snapshot, test might fail in directories like /f, /node, /test whatsoever; ensuring that it can run even in / would usually ensure that it won't fail in any other directory.

    On a side note, FHS is a standard oriented on distribution/package maintainers and applications. It doesn't forbid any usage.
    The simplest repro scenario is something like git clone https://github.com/nodejs/node && deploy_musl_32bit_casefolding_hardened_stage3_system.sh ./node && chroot ./node.

  6. gambare2 commented on Jan 10, 2026

    @gambare2

    Thanks for the clarification — that makes sense

    I’ll proceed by making test/parallel/test-node-output-sourcemaps.mjs fully cwd-agnostic, focusing on making the snapshot normalization path-aware so it doesn’t accidentally touch URLs or unrelated strings.

    I’ll keep the change minimal and scoped to the test. I’ll open a PR once I have something ready.

  7. emicovi commented on Jan 12, 2026

    @emicovi

    Hi everyone, I've opened PR #61351 to address this.

    I noticed there was some recent interest in this issue, but since there wasn't an open PR yet, I went ahead and submitted a fix for the CWD-agnostic path stripping.

    @monam2 @gambare2 apologies if I stepped on any ongoing work—since the solution was ready, I thought I'd push it to keep things moving. Please feel free to review or let me know if you had a different approach in mind!

  8. zhanglinqian commented on Feb 12, 2026

    @zhanglinqian

    I'd like to work on this issue.

  9. aduh95 commented on Feb 16, 2026

    @aduh95
    Contributor

    @legendecas did you fix that with #61590?

  10. legendecas commented on Feb 16, 2026

    @legendecas
    Member

    @aduh95 did you fix that with #61590?

    No fully. The issue is that properly transform a UNIX root / as the working directory needs more text context-awareness, and I don't think this is worthwhile to do in the test. I can hardly imagine anyone will put the node work directory into a UNIX root /.

  11. github-actions commented on Jul 20, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 90 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  12. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jul 20, 2026
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

    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.testIssues and PRs related to Node.js core tests and test infrastructure.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions