Repository navigation
[Bug]: Diff panel Working tree/Branch scopes silently empty for every in-place project — getDiffPreview workspace-root guard compares against $HOME in packaged desktop builds #4022
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Install a packaged desktop build (stable 0.0.28, Windows installer). In packaged builds the backend server is spawned with
cwd = $HOME(apps/desktop/src/app/DesktopEnvironment.ts:backendCwd: input.isPackaged ? homeDirectory : appRoot— documented in [Bug]: Packaged builds set server cwd to $HOME; ClaudeProvider auxiliary spawns leak it past project bindings #2867), and the spawn passes no--cwdflag, soServerConfig.cwdresolves toprocess.cwd()= the home directory. Verified on the live process: the backend child's cwd isC:\Users\T9. - Add any project whose repo lives outside the home directory (e.g.
D:\git\<repo>) and run a thread in place (not in a t3-managed worktree). - Open the diff panel and switch the scope dropdown to Working tree or Branch changes.
Expected behavior
The panel shows the working-tree / branch diff of the project's repository, as those scopes describe.
Actual behavior
The panel silently renders empty for every in-place project, regardless of repo size or state. Two-step failure:
-
ReviewService.getDiffPreviewcallsassertWorkspaceBoundCwd, which only accepts a cwd insideServerConfig.cwdorconfig.worktreesDir. SinceServerConfig.cwdis$HOMEin packaged builds, the project cwd (D:\git\<repo>) is rejected in ~2 ms:VcsRepositoryDetectionError: VCS repository detection failed in ReviewService.getDiffPreview: D:\git\ABW\game - Review diff preview cwd must stay within the configured workspace root. -
The client already knows about this failure mode —
apps/web/src/components/DiffPanel.tsxhas a dedicated fallback:const shouldRetryBranchDiffAtEnvironmentCwd = primaryBranchDiffPreview.error?.includes("configured workspace root") === true && serverConfig?.cwd !== undefined && serverConfig.cwd !== activeCwd;
The retry re-queries with
cwd: serverConfig.cwd— i.e. it computes the diff preview against$HOME, which is not a git repository, so the query "succeeds" with no sources and the panel shows nothing. No error ever surfaces to the user.
The only cwds that can pass the guard are t3-managed worktrees under ~/.t3/worktrees, so Working tree / Branch changes scopes only function for worktree threads. On large monorepos this leaves the diff panel with no working scope at all, because the Turn scopes are independently broken there by the checkpoint-capture timeout (#3646).
The guard itself is well-motivated — it's the validation added after #316 (arbitrary client-supplied cwd). The problem is that it validates against the server process's cwd, which in packaged desktop builds is $HOME by design, rather than against the workspace roots of registered projects. #2867 reports the same $HOME-cwd root cause from the provider-probe side; #2441 looks like this same silent-empty diff panel observed without the root cause identified.
Impact
Major degradation or frequent failure
Version or commit
0.0.28 (desktop stable, Windows installer); code paths verified identical at main @ ecb35f7
Environment
Windows 11 Pro (10.0.26200), T3 Code desktop 0.0.28, git 2.54.0.windows.1, provider claudeAgent
Logs or stack traces
server.trace.ndjson — the two spans emitted by one open of the diff panel (primary + fallback):
19:10:13 ws.rpc.review.getDiffPreview 2.0 ms Failure
VcsRepositoryDetectionError: VCS repository detection failed in
ReviewService.getDiffPreview: D:\git\ABW\game - Review diff preview cwd
must stay within the configured workspace root.
at .../app.asar/apps/server/dist/bin.mjs:37040:17
19:10:13 ws.rpc.review.getDiffPreview 437.2 ms Success (fallback at serverConfig.cwd = C:\Users\T9 — not a repo, empty result)
Backend spawn (no --cwd; ServerConfig falls back to process.cwd()):
"...\t3code\T3 Code (Alpha).exe" ...\app.asar\apps\server\dist\bin.mjs --bootstrap-fd 3
live process cwd: C:\Users\T9
Workaround
Run the thread in a t3-managed worktree (paths under ~/.t3/worktrees pass the guard). No workaround exists for in-place projects. Suggested direction: validate getDiffPreview's cwd against the registered projects' workspace roots (and thread worktree paths) instead of ServerConfig.cwd, or have the desktop app pass the project roots to the server as allowed boundaries — this would fix the diff panel while keeping the #316 hardening intact. The DiffPanel.tsx fallback should also surface an error instead of silently rendering an empty diff of the wrong directory.
Activity
t3dotgg commentedon Aug 27, 2026
Related report #5616 covers the same problem and adds useful evidence.
The August 10 runtime trace confirms the same cause as issue #4022: the registered WSL repository is outside the server startup cwd, ReviewService rejects it, and DiffPanel silently retries an unrelated directory. This is an exact duplicate of that path-validation bug, not a Git invocation problem.
I'm linking the report here before I close it as a duplicate during an automated pass. The source report and its attachments will remain available at #5616.
nbros commentedon Sep 13, 2026
It's not only related to WSL on Windows : I'm having the same issue on macOS.
With T3 Code 0.0.40 on macOS 26.6.2, using a remote connection to another macOS machine.
I'm using t3 connect:
My Working tree diff panel displays “No patch available for this selection,” while
git statusconfirms I do have changes.The server trace confirms the same error:
The project path and the git path are already exactly the same though! ("configured workspace root" is the project path right?)
But I've noticed similar issues in VS Code where it handled paths in a case sensitive manner even on macOS where case is insensitive by default.
kyledevans commentedon Sep 25, 2026
Still reproduces on
0.0.43-nightly.20260922.2096, native Windows 11 (no WSL), project atC:\dev\repos\my-app, outside%USERPROFILE%. Same trace: the firstreview.getDiffPreviewfails with "cwd must stay within the configured workspace root", the fallback atC:\Users\<me>succeeds with empty sources, and Working tree / Branch changes are both blank.There's an open fix for exactly this in #8559 (it references #8506, which is the same bug).
saphid commentedon Oct 2, 2026
Routing: Do not open a duplicate. #4022 already identifies this exact boundary failure and has a maintainer duplicate confirmation. #8506 has related client evidence. The equivalent #8559 is closed, not merged. Request agreement on the root boundary under the existing report before a substantial fix; report confirmation is not blanket approval to accept arbitrary paths or all descendants.
Environment and verification limits
Research date: 2026-10-03. Fetched
origin/mainsuccessfully; target: 7ff2eabf56. Local research host: macOS / Darwin 25.5.0 arm64, Node v24.12.0, gh 2.94.0. Main pins Effect 4.0.0-rc.115. This lane used read-only source comparisons and existing evidence; it did not launch a server, browser, desktop app, or live forge checkout. Historical regression results below are explicitly historical, not fresh runtime reproductions on this SHA. Source fingerprints and exact verification scope are in verification.json.Exact reproduction on current main
ServerConfig.cwdis A, not an ancestor of B. Register B as a project in the client.git diffis nonempty.review.getDiffPreviewRPC trace. Its first request has cwd B and fails the workspace boundary check. On web/desktop, the current DiffPanel retries at the server cwd A; if A is not a Git repo, the retry returns empty sources and the panel appears empty. If A is another repo, the retry can show A's diff instead.review.getDiffFileContentsrequest for B fails the corresponding file-content boundary check as well. A control request from inside A or the managed worktrees root passes validation.Actual versus expected
Actual:
VcsRepositoryDetectionErrorwith “Review diff preview cwd must stay within the configured workspace root.” The file-content equivalent says “Review diff file contents cwd must stay within the configured workspace root.” The client fallback can hide the failure behind an empty or wrong-repository diff. Expected: a permitted registered project can review its own checkout even outside the server launch cwd; requests for unrelated/unregistered paths remain rejected.User impact
Review is unavailable or misleading for legitimate in-place projects on another directory/volume or remote server. Managed-worktree use may avoid the guard. The existing issue includes Windows desktop traces and a macOS remote-server report, so this is broader than Windows. Web and desktop share the fallback; mobile's handling should be checked separately when implementing the same server-boundary correction.
Current-main verification
ReviewService.tsis byte-for-byte unchanged from the P19 reproduction baseline.assertWorkspaceBoundCwdaccepts only canonicalconfig.cwdandconfig.worktreesDir; it never checks project registration.DiffPanel.tsxstill retries boundary failures usingserverConfig.cwd, then selects that fallback as the displayed branch diff.CI=true TMPDIR=<C>/test-tmp vp test run apps/server/src/review/ReviewService.test.ts, exit 0, 4/4 tests passed. The executed ReviewService source and test file were verified byte-for-byte against fetched main. These tests confirm outside-root rejection and operation-specific error text; they do not exercise the proposed registered-project exception.ProjectionSnapshotQuery.getProjectShellsintegration is stale; the current metadata-only project read surface isProjectStoreV2(findActiveByWorkspaceRoot/listShells). Do not port the old service wiring unchanged.Source:
apps/server/src/review/ReviewService.ts;apps/web/src/components/DiffPanel.tsx;apps/server/src/orchestration-v2/ProjectStore.ts.Minimal proposed fix scope — no implementation
Agree that active registered project roots are an allowed review boundary, then extend validation only to that agreed set while retaining canonicalization, symlink-escape rejection, removed-registration rejection, and fail-closed query errors. Clarify whether nested cwd paths are needed; exact-root access is sufficient for this repro. Read current project metadata without repository-enrichment or a full snapshot rebuild, and retain the fast path for already allowed roots. Ensure the client does not replace a genuine rejection with another repository's diff; this fallback is part of the same incorrect-project review behavior. No arbitrary filesystem access, unrelated diff features, or new user-facing configuration.
Evidence available
🤖 Generated with Claude Code
nbrosei commentedon Oct 3, 2026
Diffs are still broken in t3 code 0.0.45 (6c8fed3).
This "working tree" diff view has never worked for me at all in t3 code.
nbros commentedon Oct 3, 2026
Reproduced on T3 Code 0.0.45, using macOS desktop connected over SSH to a macOS server.
The t3 code server starts in
/Users/claude, while the registered project is/Users/Shared/git/t3code. Diff → Working tree shows “No patch available for this selection,” althoughgit diff HEADin that checkout shows changes.Remote traces confirm:
The validation rejects the registered project because it is outside the server’s startup directory. The UI then silently retries against
/Users/claude, which isn’t a Git repository, masking the error.Whereas a local checkout under
~/git/t3codeworks.This also affects remote background-service environments, beyond the packaged Windows desktop case originally reported.
saphid commentedon Oct 3, 2026
Thanks for the remote repro. That matches the cause exactly: the registered project is outside the server's startup directory, review validation rejects it, and the client silently falls back to the server cwd.
#15014 fixes this case. It lets review reads use any registered project root (and its subfolders), not just the launch directory. Symlink escapes and removed projects are still rejected. It isn't tied to the Windows desktop path, so it should cover SSH and background-service environments like yours. If you're able to try that branch on your setup, a confirmation there would help.
nbros commentedon Oct 4, 2026
@saphid Thanks! I verified your fix on my setup with a server starting in
/Users/claude, while the registered project lives at/Users/Shared/git/t3code. The remote review API now returns that project’s actual changes and the Diff panel shows the working tree changes.For clarity, I asked Codex to backport #15014 at
8a17f359onto stable v0.0.45, adapting the project lookup to V1 persistence to avoid the V2 migration which I'm avoiding at the moment (I prefer staying on stable atm).So I haven’t tested your exact full PR branch unchanged, but at least the backported fix resolves my reported case.
Thank you!
fix(server): allow reviews within registered project roots (upstream p…
fix(server): allow reviews within registered project roots (upstream p…
pablo-kitz commentedon Oct 8, 2026
Still reproducing on 0.0.46-nightly.20261007.2787 on Windows desktop, with both the WSL Ubuntu backend and native Windows environment (observed October 8, 2026).
Diff counts are visible, but opening Uncommitted changes or Branch changes displays “No patch available for this selection.” Standard Git commands confirm the repository contains changes.
WSL evidence
The registered repository is
/home/pablo/code/repo, while the backend process starts in/mnt/c/Users/<user>.The server trace records:
Capturing Git process arguments while reopening the diff panel confirms the fallback checks the unrelated startup directory:
That directory is not a Git repository. Running the equivalent command against
/home/pablo/code/aleph-kit, using the backend process's environment, returnstrue.The installed runtime's
ReviewService.assertWorkspaceBoundCwdstill validates againstconfig.cwdand managed worktree directories. ItsDiffPanelstill retries atserverConfig.cwdwhen the primary request reports the configured-workspace-root error. This masks the original validation failure with an empty preview.Native Windows evidence
The Windows backend trace independently contains:
Additional symptom
The turn/checkpoint selection also shows “No patch available for this selection” on my setup. The investigation above confirms the cause for working-tree/branch previews; it has not established that the checkpoint symptom has the same cause.
No local runtime patches or configuration changes were applied during diagnosis. This confirms the registered-project-root restriction and silent fallback remain reproducible in the above nightly build.
fix(server): allow reviews within registered project roots (upstream p…
fix(server): allow reviews within registered project roots (upstream p…
saphid commentedon Oct 9, 2026
Thanks for the detailed trace. That nightly doesn't include the fix yet: #15014 is still open, waiting on maintainer review. Your WSL case matches what it fixes. The registered project
/home/pablo/code/reposits outside the directory the backend started in (/mnt/c/Users/<user>), so the old workspace-root guard rejects it. #15014 checks against registered project roots instead.I haven't verified the native Windows environment with #15014. Path comparison there (drive letters, case, separators) wasn't part of its tests. If the native Windows trace shows the same "must stay within the configured" error, please paste the two paths it compares, and I'll check them against the fix.