Skip to content

[Bug]: Stack trace paths are mangled and the code frame is missing when the project path contains parentheses #16548

Open

Description

@trackoor

Version

30.5.2

Steps to reproduce

mkdir "jest (copy)" && cd "jest (copy)"
npm init -y && npm i -D [email protected]

sum.test.js:

test("sum", () => {
  [1].forEach((n) => {
    expect(n).toBe(2);
  });
});
npx jest

Expected behavior

The same relative stack paths (and code frame when running untransformed or with anonymous frames) as in a directory without parentheses:

      1 | test("sum", () => {
      2 |   [1].forEach((n) => {
    > 3 |     expect(n).toBe(2);
        |               ^
      4 |   });
      5 | });
      6 |

      at toBe (sum.test.js:3:15)
          at Array.forEach (<anonymous>)
      at Object.forEach (sum.test.js:2:7)

Actual behavior

Every frame path in the stack trace is mangled:

      at toBe (/home/me/jest (copy)../../../sum.test.js:3:15)
          at Array.forEach (<anonymous>)
      at Object.forEach (/home/me/jest (copy)../../../sum.test.js:2:7)

When running without a source-map transform (npx jest --transform="{}"), where the top frame is anonymous (at /home/me/jest (copy)/sum.test.js:3:15), the code frame is also missing completely:

      at /home/me/jest (copy)../../../sum.test.js:3:15
          at Array.forEach (<anonymous>)
      at Object.<anonymous> (/home/me/jest (copy)../../../sum.test.js:2:7)

Additional context

Two causes in packages/jest-message-util/src/index.ts:

  • formatPath uses /(^\s*at .*?\(?)([^()]+)(:\d+:\d+\)?.*$)/, so the captured path (match[2]) is only the segment after the last ) (/sum.test.js), which path.relative(config.rootDir, match[2]) turns into ../../../sum.test.js and concatenates right after match[1].
  • getTopFrame calls stack-utils parseLine, which splits an anonymous frame at /home/me/jest (copy)/sum.test.js:3:15 into function /home/me/jest and non-absolute file copy)/sum.test.js, so formatStackTrace skips rendering the code frame.

Directories like C:\Users\Jane (Work)\... or project (1) hit this. Unchanged on main (7261444).

Environment

System:
  OS: Linux 6.1 Debian GNU/Linux 12 (bookworm)
  CPU: (64) x64 Intel(R) Xeon(R) CPU @ 2.80GHz
Binaries:
  Node: 26.13.0
  npm: 11.20.0
npmPackages:
  jest: 30.5.2 => 30.5.2

Credit: https://ucsbplse.github.io/

Activity

  1. X6M-Work commented on Nov 7, 2026

    @X6M-Work

    Thanks for the precise write-up, both causes were exactly where you pointed. I opened #16549 with a fix:

    • formatPath now first matches frames whose location is an absolute path or file:// URL running to the end of the line, so the path keeps its parentheses. Other frames, including eval ones, still go through the existing regex.
    • getTopFrame parses anonymous frames like at /a (b)/c.js:1:2 itself instead of going through stack-utils, so the code frame comes back.

    I checked it with your reproduction in a jest (copy) directory on Windows: the paths print as sum.test.js:3:15, and with --transform={} the code frame is shown again.

  2. abraham21587 commented on Nov 10, 2026

    @abraham21587

    I’d like to work on this

  3. added a commit that references this issue on Nov 11, 2026
    8bb4943
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