[GH-ISSUE #4496] [Bug] MSIX AppData root selection trims caller-supplied directory paths #1782

Closed
opened 2026-10-16 21:10:11 +00:00 by bsakaguchi · 3 comments
Owner

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

Before submitting

  • Searched open/closed APPDATA whitespace and windowsAppDataRoots reports; no matching issue found.
  • No credentials or private target data included.

Area

Setup, packaging, or upgrade

Observed behavior

Source-confirmed defect; no native Windows reproduction claimed. windowsAppDataRoots calls .trim() on caller-supplied APPDATA and LOCALAPPDATA paths. A selected directory whose final component contains significant whitespace is silently changed before config/package discovery. This violates AGENTS.md's preservation of caller-selected paths and can select another directory or miss the package marker.

Reproduction

NOT_ENOUGH_INFO for historical/native Windows reproduction. Source: src/application/MsixPackageStorage.ts, windowsAppDataRoots returns env.APPDATA?.trim() || fallback and the same for LOCALAPPDATA. Proposed real-filesystem boundary check: two distinct profile roots named Roaming/Roaming and Local/Local , with caller environment selecting the latter. Invoke supportedClients/setup/doctor with injected Windows platform and observe the wrong config selection. Native Windows extended-length path behavior remains to verify.

Expected behavior

Keep nonempty selected path values exactly. Apply the documented home/AppData fallback only for unset or empty values. Normalize file identity through filesystem-owned path operations rather than trimming a path as display text.

Impact and scope

Source-derived: this shared owner feeds Claude Desktop config and MSIX package discovery/storage ownership. A changed LOCALAPPDATA can make package storage appear absent and allow an incorrect AppData fallback. Actual affected installation frequency is unknown. Filesystem path selection can be verified on the host without claiming a native Windows app run.

REA version

6.5.0; source base fe2a398dd9 with ongoing local audit changes.

Runtime and platform

Source review on macOS arm64, Node24.18.0. Native Windows unverified.

Target and artifact context

Explicit APPDATA / LOCALAPPDATA configuration paths.

Interface

Shared setup, doctor and uninstall configuration owner.

Earliest failure stage

Setup or provider admission

Relevant output or evidence

src/application/MsixPackageStorage.ts:windowsAppDataRoots; consumers ClaudeDesktopConfigLocation.ts, msixPackagesDirectory, and package-private launcher checks in SupportedClients.ts. This report is source evidence only at filing.

Typed outcome or recovery expected

Selected roots remain byte-for-byte caller values; unset/empty roots retain current fallback. Setup and doctor agree with that location; MSIX ownership must not be inferred from an inadvertently different directory.

Analysis or suspected cause

Display-style string cleanup at the owning path boundary. Remove trimming there and validate directly related consumer selection. Adjacent to #4432 and #4378 but an independent input-preservation defect.

Originally created by @morluto on GitHub (Oct 16, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4496 ### Before submitting - [x] Searched open/closed APPDATA whitespace and windowsAppDataRoots reports; no matching issue found. - [x] No credentials or private target data included. ### Area Setup, packaging, or upgrade ### Observed behavior **Source-confirmed defect; no native Windows reproduction claimed.** `windowsAppDataRoots` calls `.trim()` on caller-supplied APPDATA and LOCALAPPDATA paths. A selected directory whose final component contains significant whitespace is silently changed before config/package discovery. This violates AGENTS.md's preservation of caller-selected paths and can select another directory or miss the package marker. ### Reproduction NOT_ENOUGH_INFO for historical/native Windows reproduction. Source: `src/application/MsixPackageStorage.ts`, windowsAppDataRoots returns `env.APPDATA?.trim() || fallback` and the same for LOCALAPPDATA. Proposed real-filesystem boundary check: two distinct profile roots named `Roaming`/`Roaming ` and `Local`/`Local `, with caller environment selecting the latter. Invoke supportedClients/setup/doctor with injected Windows platform and observe the wrong config selection. Native Windows extended-length path behavior remains to verify. ### Expected behavior Keep nonempty selected path values exactly. Apply the documented home/AppData fallback only for unset or empty values. Normalize file identity through filesystem-owned path operations rather than trimming a path as display text. ### Impact and scope Source-derived: this shared owner feeds Claude Desktop config and MSIX package discovery/storage ownership. A changed LOCALAPPDATA can make package storage appear absent and allow an incorrect AppData fallback. Actual affected installation frequency is unknown. Filesystem path selection can be verified on the host without claiming a native Windows app run. ### REA version 6.5.0; source base fe2a398dd9ab290ba6cb3411403d319cec8d07a2 with ongoing local audit changes. ### Runtime and platform Source review on macOS arm64, Node24.18.0. Native Windows unverified. ### Target and artifact context Explicit APPDATA / LOCALAPPDATA configuration paths. ### Interface Shared setup, doctor and uninstall configuration owner. ### Earliest failure stage Setup or provider admission ### Relevant output or evidence `src/application/MsixPackageStorage.ts:windowsAppDataRoots`; consumers `ClaudeDesktopConfigLocation.ts`, `msixPackagesDirectory`, and package-private launcher checks in SupportedClients.ts. This report is source evidence only at filing. ### Typed outcome or recovery expected Selected roots remain byte-for-byte caller values; unset/empty roots retain current fallback. Setup and doctor agree with that location; MSIX ownership must not be inferred from an inadvertently different directory. ### Analysis or suspected cause Display-style string cleanup at the owning path boundary. Remove trimming there and validate directly related consumer selection. Adjacent to #4432 and #4378 but an independent input-preservation defect.
Author
Owner

@pablodiazjorge commented on GitHub (Oct 16, 2026):

A native Windows data point, since the report leaves that open.

Host: Windows 11 Pro 10.0.26300 on NTFS, Node 24.18.0, main at 781d5751a, built with npm run compile (setup --dry-run does not need the native addon).

Windows keeps a trailing space in any path component except the last one. In a scratch folder I created sibling directories Roaming and Roaming , each with its own Claude\claude_desktop_config.json and a marker file. Node, cmd (type "<scratch>\Roaming \marker.txt") and PowerShell 5.1 ([IO.File]::ReadAllText) all read the file under Roaming , so for anything beneath them the two names are distinct directories. Win32 strips trailing spaces only from the final component, and the AppData root is never the final component here.

Then, with APPDATA set to <scratch>\Roaming and LOCALAPPDATA to <scratch>\Local:

node scripts/rea.mjs setup --client claude_desktop --dry-run --format json
  • The planned configure_client:claude_desktop action targets <scratch>\Roaming\Claude\claude_desktop_config.json, with its backup path beside it: the trimmed directory, not the selected one. doctor.identity.registrations and clientStates report the same path.
  • In the same output, the VS Code, Trae and Devin entries resolve under <scratch>\Roaming \, so within one run Claude Desktop and those clients use different AppData roots.

So the trim does select another directory on a real Windows host. Not run: an applied setup, MSIX package discovery with a trimmed LOCALAPPDATA, and a value with a leading space.

<!-- gh-comment-id:6217874339 --> @pablodiazjorge commented on GitHub (Oct 16, 2026): A native Windows data point, since the report leaves that open. Host: Windows 11 Pro 10.0.26300 on NTFS, Node 24.18.0, `main` at `781d5751a`, built with `npm run compile` (`setup --dry-run` does not need the native addon). Windows keeps a trailing space in any path component except the last one. In a scratch folder I created sibling directories `Roaming` and `Roaming `, each with its own `Claude\claude_desktop_config.json` and a marker file. Node, cmd (`type "<scratch>\Roaming \marker.txt"`) and PowerShell 5.1 (`[IO.File]::ReadAllText`) all read the file under `Roaming `, so for anything beneath them the two names are distinct directories. Win32 strips trailing spaces only from the final component, and the AppData root is never the final component here. Then, with `APPDATA` set to `<scratch>\Roaming ` and `LOCALAPPDATA` to `<scratch>\Local`: ```powershell node scripts/rea.mjs setup --client claude_desktop --dry-run --format json ``` - The planned `configure_client:claude_desktop` action targets `<scratch>\Roaming\Claude\claude_desktop_config.json`, with its backup path beside it: the trimmed directory, not the selected one. `doctor.identity.registrations` and `clientStates` report the same path. - In the same output, the VS Code, Trae and Devin entries resolve under `<scratch>\Roaming \`, so within one run Claude Desktop and those clients use different AppData roots. So the trim does select another directory on a real Windows host. Not run: an applied setup, MSIX package discovery with a trimmed `LOCALAPPDATA`, and a value with a leading space.
Author
Owner

@PK-SANGAMESWAR commented on GitHub (Oct 16, 2026):

Hi, I'd like to work on this issue. I'll investigate the path-handling behaviour, add regression tests, and submit a pull request with the fix. Please let me know if anyone is already working on it.

<!-- gh-comment-id:6218525079 --> @PK-SANGAMESWAR commented on GitHub (Oct 16, 2026): Hi, I'd like to work on this issue. I'll investigate the path-handling behaviour, add regression tests, and submit a pull request with the fix. Please let me know if anyone is already working on it.
Author
Owner

@morluto commented on GitHub (Oct 17, 2026):

Revalidated and closing as fixed on main abb54ce3743dd51a54304833a6e081b89243a5e8. The runtime fixes were already published in 9abdad335; this reconciliation adds missing focused regressions in abb54ce37.

9abdad335 preserves nonempty caller APPDATA/LOCALAPPDATA strings literally, with fallback only for unset/empty values. Added exact string controls (including all-space input) and a native filesystem control with distinct trailing-space roots plus a conflicting trimmed root. The selected configuration remains the literal path. All three controls fail on pre-fix6d5281407, where the path was trimmed. This checks path preservation on the host; it is not a claim about Windows extended-length path semantics.

Validation:82 tests across four configuration/CLI files passed. Seven newly checked-in controls ran against pre-fix6d5281407: six failed for the expected original defects and one existing-behavior guard passed; all seven pass now. Typecheck/lint, formatting, test discovery (1563files exactly once) and pre-push checks passed. Related header/skill/doctor reconciliation added186passing checks across nine other files.

Scope: macOS arm64 / Node24.18.0; controlled native files, source/platform-selected Windows adapters and real REA CLI commands. No native Windows Claude app,3P deployment, Windows/Linux permission fault or provider/target execution was verified. No full-suite or performance improvement claim.

<!-- gh-comment-id:6242953581 --> @morluto commented on GitHub (Oct 17, 2026): Revalidated and closing as fixed on main `abb54ce3743dd51a54304833a6e081b89243a5e8`. The runtime fixes were already published in `9abdad335`; this reconciliation adds missing focused regressions in `abb54ce37`. 9abdad335 preserves nonempty caller APPDATA/LOCALAPPDATA strings literally, with fallback only for unset/empty values. Added exact string controls (including all-space input) and a native filesystem control with distinct trailing-space roots plus a conflicting trimmed root. The selected configuration remains the literal path. All three controls fail on pre-fix6d5281407, where the path was trimmed. This checks path preservation on the host; it is not a claim about Windows extended-length path semantics. Validation:82 tests across four configuration/CLI files passed. Seven newly checked-in controls ran against pre-fix6d5281407: six failed for the expected original defects and one existing-behavior guard passed; all seven pass now. Typecheck/lint, formatting, test discovery (1563files exactly once) and pre-push checks passed. Related header/skill/doctor reconciliation added186passing checks across nine other files. Scope: macOS arm64 / Node24.18.0; controlled native files, source/platform-selected Windows adapters and real REA CLI commands. No native Windows Claude app,3P deployment, Windows/Linux permission fault or provider/target execution was verified. No full-suite or performance improvement 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#1782
No description provided.