[GH-ISSUE #6644] [Bug] macOS and Linux Hopper launcher candidate paths use host path separators instead of POSIX #4024

Closed
opened 2026-10-31 00:46:09 +00:00 by bsakaguchi · 2 comments
Owner

Originally created by @keshavagr025 on GitHub (Oct 23, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6644

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Setup, packaging, or upgrade

Observed behavior

src/application/MacHopperPaths.ts and src/application/LinuxHopper.ts use ambient join from "node:path".

On non-POSIX/Windows environments, join emits Windows backslashes (\) for macOS bundle structures and Linux directories (e.g. \Applications\Hopper Disassembler.app\...). This breaks candidate matching and causes tests to fail:

  1. src/application/MacHopperPaths.test.ts (2 failures: expected /Applications/..., received \Applications\...)
  2. src/application/Doctor.test.ts (doctor installed Hopper discovery > checks the canonical user install after the system launcher returns undefined)

Reproduction

  1. On a Windows checkout (or an environment where node:path defaults to win32), run:
  2. npm run test:local -- src/application/MacHopperPaths.test.ts
  3. npm run test:local -- src/application/Doctor.test.ts
  4. Observe 2 failures in MacHopperPaths.test.ts and 1 failure in Doctor.test.ts.

Expected behavior

macOS Hopper application bundle paths (/Applications/..., $HOME/Applications/Hopper Disassembler.app/Contents/MacOS/hopper) and Linux user paths (.local/share/rea/hopper/...) represent Unix filesystem targets. They must always use POSIX path separators (/), independent of the host OS running REA.

Impact and scope

  • Frequency: 100% reproducible on Windows checkouts.
  • Scope: Hopper candidate discovery in DoctorDiagnostics.ts and MacHopperPaths.ts.
  • Severity: Breaks doctor diagnostics and candidate matching for Hopper on non-POSIX hosts.

REA version

6.7.0 (commit c12d9eda8)

Runtime and platform

Node 22.19.0; Windows 11 x64

Target and artifact context

macOS Hopper .app bundle; Linux Hopper launcher paths

Interface

CLI

Earliest failure stage

Request parsing or validation

Relevant output or evidence

Command run:
npm run test:local -- src/application/MacHopperPaths.test.ts

Failure output:

FAIL services src/application/MacHopperPaths.test.ts > macOS Hopper launcher paths > keeps canonical system and user candidates ahead of renamed bundles
AssertionError: expected [ …(2) ] to deeply equal [ …(2) ]

- Expected
+ Received
  [
-   "/Applications/Hopper Disassembler.app/Contents/MacOS/hopper",
-   "/fixture/home/Applications/Hopper Disassembler.app/Contents/MacOS/hopper",
+   "\\Applications\\Hopper Disassembler.app\\Contents\\MacOS\\hopper",
+   "\\fixture\\home\\Applications\\Hopper Disassembler.app\\Contents\\MacOS\\hopper",
  ]


### Typed outcome or recovery expected


---

### **Typed outcome or recovery expected**
```markdown
`macHopperCanonicalLauncherCandidates(home)` and `linuxHopperLauncherPath(home)` should always return normalized POSIX strings using `/`.


### Analysis or suspected cause

- `src/application/MacHopperPaths.ts`: Line 2 imports ambient `join` from `"node:path"` instead of `posix.join`.
- `src/application/LinuxHopper.ts`: Line 390 uses ambient `join(home, ".local/share/rea/hopper/bin/Hopper")`.

Solution:
1. Use `posix.join` from `"node:path"` in both files.
2. Normalize home directory slashes (`homeDirectory.replaceAll("\\", "/")`) before joining so bundle candidates consistently use canonical POSIX separators.
3. Update `MacHopperPaths.test.ts` to assert against normalized POSIX paths.


### Additional context

I have investigated the root cause, implemented the fix, and verified that all 35 tests across `MacHopperPaths.test.ts` and `Doctor.test.ts` pass, along with `npm run check:fast`.

Please assign this issue to me and I will submit the pull request!
Originally created by @keshavagr025 on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6644 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Setup, packaging, or upgrade ### Observed behavior `src/application/MacHopperPaths.ts` and `src/application/LinuxHopper.ts` use ambient `join` from `"node:path"`. On non-POSIX/Windows environments, `join` emits Windows backslashes (`\`) for macOS bundle structures and Linux directories (e.g. `\Applications\Hopper Disassembler.app\...`). This breaks candidate matching and causes tests to fail: 1. `src/application/MacHopperPaths.test.ts` (2 failures: expected `/Applications/...`, received `\Applications\...`) 2. `src/application/Doctor.test.ts` (`doctor installed Hopper discovery > checks the canonical user install after the system launcher` returns `undefined`) ### Reproduction 1. On a Windows checkout (or an environment where `node:path` defaults to `win32`), run: 2. `npm run test:local -- src/application/MacHopperPaths.test.ts` 3. `npm run test:local -- src/application/Doctor.test.ts` 4. Observe 2 failures in `MacHopperPaths.test.ts` and 1 failure in `Doctor.test.ts`. ### Expected behavior macOS Hopper application bundle paths (`/Applications/...`, `$HOME/Applications/Hopper Disassembler.app/Contents/MacOS/hopper`) and Linux user paths (`.local/share/rea/hopper/...`) represent Unix filesystem targets. They must always use POSIX path separators (`/`), independent of the host OS running REA. ### Impact and scope - Frequency: 100% reproducible on Windows checkouts. - Scope: Hopper candidate discovery in `DoctorDiagnostics.ts` and `MacHopperPaths.ts`. - Severity: Breaks doctor diagnostics and candidate matching for Hopper on non-POSIX hosts. ### REA version 6.7.0 (commit c12d9eda8) ### Runtime and platform Node 22.19.0; Windows 11 x64 ### Target and artifact context macOS Hopper .app bundle; Linux Hopper launcher paths ### Interface CLI ### Earliest failure stage Request parsing or validation ### Relevant output or evidence Command run: `npm run test:local -- src/application/MacHopperPaths.test.ts` Failure output: ```text FAIL services src/application/MacHopperPaths.test.ts > macOS Hopper launcher paths > keeps canonical system and user candidates ahead of renamed bundles AssertionError: expected [ …(2) ] to deeply equal [ …(2) ] - Expected + Received [ - "/Applications/Hopper Disassembler.app/Contents/MacOS/hopper", - "/fixture/home/Applications/Hopper Disassembler.app/Contents/MacOS/hopper", + "\\Applications\\Hopper Disassembler.app\\Contents\\MacOS\\hopper", + "\\fixture\\home\\Applications\\Hopper Disassembler.app\\Contents\\MacOS\\hopper", ] ### Typed outcome or recovery expected --- ### **Typed outcome or recovery expected** ```markdown `macHopperCanonicalLauncherCandidates(home)` and `linuxHopperLauncherPath(home)` should always return normalized POSIX strings using `/`. ### Analysis or suspected cause - `src/application/MacHopperPaths.ts`: Line 2 imports ambient `join` from `"node:path"` instead of `posix.join`. - `src/application/LinuxHopper.ts`: Line 390 uses ambient `join(home, ".local/share/rea/hopper/bin/Hopper")`. Solution: 1. Use `posix.join` from `"node:path"` in both files. 2. Normalize home directory slashes (`homeDirectory.replaceAll("\\", "/")`) before joining so bundle candidates consistently use canonical POSIX separators. 3. Update `MacHopperPaths.test.ts` to assert against normalized POSIX paths. ### Additional context I have investigated the root cause, implemented the fix, and verified that all 35 tests across `MacHopperPaths.test.ts` and `Doctor.test.ts` pass, along with `npm run check:fast`. Please assign this issue to me and I will submit the pull request!
bsakaguchi 2026-10-31 00:46:09 +00:00
  • closed this issue
  • added the
    bug
    triage
    labels
Author
Owner

@dark13b commented on GitHub (Oct 23, 2026):

I'd like to take this one.

I will reproduce the three failures on Windows 11 first. Plan: build the macOS and Linux Hopper candidate paths with path.posix so they do not depend on the host OS, and keep the existing tests as the regression coverage.

<!-- gh-comment-id:6369055932 --> @dark13b commented on GitHub (Oct 23, 2026): I'd like to take this one. I will reproduce the three failures on Windows 11 first. Plan: build the macOS and Linux Hopper candidate paths with `path.posix` so they do not depend on the host OS, and keep the existing tests as the regression coverage.
Author
Owner

@dark13b commented on GitHub (Oct 23, 2026):

This is already fixed on main by #5235 (b1ff86832), which switched the macOS and Linux Hopper launcher paths to posix.join. On current main, npm run test:focused -- src/application/MacHopperPaths.test.ts src/application/Doctor.test.ts passes (77 of 77 on Windows 11), so the three failures do not reproduce. The issue can be closed.

I am dropping my claim.

<!-- gh-comment-id:6369501477 --> @dark13b commented on GitHub (Oct 23, 2026): This is already fixed on main by #5235 (b1ff86832), which switched the macOS and Linux Hopper launcher paths to `posix.join`. On current main, `npm run test:focused -- src/application/MacHopperPaths.test.ts src/application/Doctor.test.ts` passes (77 of 77 on Windows 11), so the three failures do not reproduce. The issue can be closed. I am dropping my claim.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#4024
No description provided.