pingdotgg / pingdotgg/t3code

[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

Open
#4,022 2 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
23k
Forks
5.9k
Avg merge
11h 14m
Merged PRs (30d)
357

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
  1. 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 #2867), and the spawn passes no --cwd flag, so ServerConfig.cwd resolves to process.cwd() = the home directory. Verified on the live process: the backend child's cwd is C:\Users\T9.
  2. 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).
  3. 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:

  1. ReviewService.getDiffPreview calls assertWorkspaceBoundCwd, which only accepts a cwd inside ServerConfig.cwd or config.worktreesDir. Since ServerConfig.cwd is $HOME in 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.

  2. The client already knows about this failure mode — apps/web/src/components/DiffPanel.tsx has 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 @ ecb35f75

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with ReviewService.getDiffPreview and its assertWorkspaceBoundCwd guard in apps/server, then trace project workspace registration and the desktop spawn setup in apps/desktop/src/app/DesktopEnvironment.ts. Inspect the retry path in apps/web/src/components/DiffPanel.tsx. Done means in-place projects outside $HOME show their Working tree and Branch changes diffs without silently retrying against an empty directory, while the existing cwd boundary remains enforced.

Written by the indexing model from the issue text.

Assessment

Tech stack
git, typescript
Domain
backend, desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
64/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.