Skip to content

[Bug]: VCS spawn error fires even with Git integration disabled and git not installed #10351

Description

@wyjwjl

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/desktop

Steps to reproduce

  1. On Windows with no git on PATH (verified: git not recognized; folder is not a repo, no .git).
  2. Open any plain folder, e.g. C:\Users\PC\Documents\newproject.
  3. Go to Settings → Version Control → toggle Git OFF (shows "Not available on this server").
  4. Reopen the folder.

Expected behavior

With Git integration disabled, the app should never attempt to spawn git. And when the git binary is missing entirely, the worktree probe should fail silently instead of surfacing an error.

Actual behavior

An error notification appears on every folder open:

VCS process failed to spawn in GitVcsDriver.isInsideWorkTree: git (C:\Users\PC\Documents\newproject)

So isInsideWorkTree still spawns git despite the toggle being OFF, and a missing binary is reported as an error rather than handled gracefully.

Regression: the previous build did not show this error; it appeared only after updating to this nightly.

Impact

Minor bug or occasional failure

Version or commit

0.0.39-nightly.20260906.1293

Environment

Windows 11, T3 Code desktop (Nightly), git not installed, opened folder is not a git repository.

Logs or stack traces

VCS process failed to spawn in GitVcsDriver.isInsideWorkTree: git (C:\Users\PC\Documents\newproject)

Screenshots, recordings, or supporting files

Image Image

Workaround

Install Git (spawn then succeeds and the driver quietly reports "not a repo"),
or set Git fetch interval to 0 to reduce repeated background spawns
(the error on folder open remains).

Source hint

The probe is git -C <cwd> rev-parse --is-inside-work-tree, and a missing
binary is surfaced as an error instead of "not a repository":

t3code/apps/server/src/vcs/GitVcsDriver.ts (~L275-285)

const isInsideWorkTree = (cwd) =>
  gitCommand(vcsProcess, "GitVcsDriver.isInsideWorkTree", cwd,
    ["rev-parse", "--is-inside-work-tree"],
    { allowNonZeroExit: true, timeoutMs: 5_000, maxOutputBytes: 4_096 },
  ).pipe(Effect.map((r) => r.exitCode === 0 && r.stdout.trim() === "true"));

t3code/packages/contracts/src/vcs.ts (~L60-85)

export class VcsProcessSpawnError ... {
  override get message(): string {
    return `VCS process failed to spawn in ${this.operation}: ${this.command} (${this.cwd})`;

t3code/apps/server/src/vcs/VcsDriverRegistry.ts (~L55-105)

const git = yield* GitVcsDriver.makeVcsDriver;
...
return yield* detectWithDriver("git", git, input.cwd); // -> detectRepository -> isInsideWorkTree

Detection consults only VcsProjectConfig.resolveKind (.t3code/vcs.json
kind selector) — ServerSettings has automaticGitFetchInterval,
backgroundActivity, sourceControlWritingStyle, but no git.enabled /
vcs.enabled flag. Unconditional callers include
GitWorkflowService.detectGitRepositoryForStatus
(apps/server/src/git/GitWorkflowService.ts ~L110-175) and
VcsStatusBroadcaster.getStatus/refreshStatus
(apps/server/src/vcs/VcsStatusBroadcaster.ts ~L200-280).

As a result, with the desktop Git toggle OFF and no git on PATH, every
folder open / turn still spawns git and the ENOENT surfaces as a
notification error.

Suggested fix

  1. Treat ProcessSpawnError with ENOENT (binary missing) in the
    isInsideWorkTree path as "not a repository" (return false) instead
    of raising VcsProcessSpawnError.
  2. Gate VcsDriverRegistry.detect on a real git-enabled setting wired to
    the Version Control toggle, so OFF means zero git spawns.

(Line numbers from main as of 2026-09-06; the behavior was verified on
0.0.39-nightly.20260906.1293.)

Activity

  1. juliusmarminge commented on Sep 6, 2026

    @juliusmarminge
    Member

    Thanks for the thorough write-up and the source pointers — this checks out on current main.

    What's going on

    GitVcsDriver.isInsideWorkTree always spawns git -C <cwd> rev-parse --is-inside-work-tree. Non-zero “not a repo” (exit 128) is already handled via allowNonZeroExit: true and becomes false. A missing git binary is a spawn failure (VcsProcessSpawnError) and is not treated as “not a repository,” so it bubbles out.

    Folder open hits that probe through VCS status (VcsStatusBroadcaster → GitWorkflowService.detectGitRepositoryForStatus → VcsDriverRegistry.detect → detectRepository → isInsideWorkTree). The toast text matches VcsProcessSpawnError.message in packages/contracts/src/vcs.ts.

    The Git switch is not an off switch

    In Settings → Version Control, the Git control is a disabled availability indicator, not a user setting:

    const enabled = item.status === "available" && item.implemented;
    <Switch checked={enabled} disabled aria-label={`${item.label} availability`} />

    “Not available on this server” is SourceControlDiscovery correctly reporting status: "missing" when git --version fails. There is no git.enabled / vcs.enabled flag in ServerSettings. VcsDriverRegistry.detect only consults .t3code/vcs.json (VcsProjectConfig.resolveKind) and then always tries the git driver.

    So Git OFF here means “git not found,” not “do not spawn git.” Discovery already knows git is missing; detect does not use that result.

    Contrast in-tree

    RepositoryIdentityResolver already treats a failed git rev-parse as “no repo” (Effect.option → null). GitHubCli / AzureDevOpsCli / SourceControlDiscovery treat a missing binary as unavailable. isInsideWorkTree does not, which is why installing Git makes the error disappear (spawn succeeds, then “not a repo” is silent).

    Not a duplicate of

    No open PR covers this missing-binary case.

    Suggested fix (minimal first)

    1. In isInsideWorkTree (and ideally detectRepository), map VcsProcessSpawnError for a missing git (ENOENT / PlatformError NotFound on spawn) to false / null instead of failing. That matches the other CLI “unavailable” handling and the reporter’s expected behavior.
    2. Optional follow-up: short-circuit VcsDriverRegistry.detect when discovery already marked git missing, so we don’t spawn at all.
    3. A real user-facing “disable Git integration” setting would be a separate enhancement — it does not exist today.

    Workaround remains: install Git, or live with the toast on folder open (fetch interval 0 does not stop the initial detect).

  2. added
    via-triageFiled through npx t3 triage
    bugSomething is broken or behaving incorrectly.
    on Sep 6, 2026
  3. added a commit that references this issue on Sep 10, 2026
    f8d8abb
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

    bugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions