Skip to content

[Bug]: Background git fetch fills up entire disk when fetch exceeds the 5s timeout (regression of #1965) #3525

Description

@Jardo-51

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 (VCS driver) / apps/desktop

Steps to reproduce

  1. Open a Git repository in T3 Code whose origin is far enough behind that a full git fetch takes longer than 5 seconds (e.g. a repo cloned a while ago and not fetched since, a large repo, or a slow connection). T3 Code's own repo reproduces this reliably after a stale clone.
  2. Leave the app open. It runs background upstream-status refreshes (fetchRemoteForStatus) on a ~15s interval to compute the ahead/behind indicator.
  3. Each refresh runs git fetch --quiet --no-tags <remote> with a hard 5s timeout (STATUS_UPSTREAM_REFRESH_TIMEOUT). Because the fetch can't finish in 5s, the git process is killed (timeoutBehavior: "error").
  4. Watch .git/objects/pack/ over time — tmp_pack_* files accumulate (~one per refresh cycle). git count-objects -vH shows size-garbage climbing.
  5. Disk usage grows without bound until the drive fills.

Expected behavior

Background status fetches must never leave temporary packfiles behind. On timeout/failure the orphaned tmp_pack_* should be cleaned up, and the loop should not get stuck re-leaking forever (a fetch that can never complete within the timeout should not be retried in a way that re-downloads the full backlog every cycle).

Actual behavior

Background upstream-status git fetch leaks tmp_pack files when fetch exceeds the 5s timeout. The files keep accumulating until the entire disk gets full.

The 5s-timeout fetch is hard-killed mid-git index-pack, leaving a partial tmp_pack_* orphan; git does not remove its temp file when killed. Crucially, until one fetch completes, the local never catches up, so every subsequent fetch re-downloads the entire backlog (e.g. a --pack_header=2,24748 pack here), is guaranteed to exceed 5s, and orphans again — every ~15s, indefinitely.

In my case this produced 5,563 tmp_pack_* files totaling ~24 GB before I noticed (the only thing that stopped it was a reboot). Manually running a single git fetch origin to completion took ~34 s — i.e. ~7× the 5s budget — which is exactly why the background fetch could never succeed. After that one completed fetch, the local caught up and the leak stopped (subsequent small fetches finish within 5s).

Root cause

In apps/server/src/vcs/GitVcsDriverCore.ts:

  • STATUS_UPSTREAM_REFRESH_TIMEOUT = Duration.seconds(5) (and …_INTERVAL = 15s, …_FAILURE_COOLDOWN = 5s).
  • fetchRemoteForStatus runs ["--git-dir", gitCommonDir, "fetch", "--quiet", "--no-tags", remoteName] with timeoutMs = that 5s.
  • In apps/server/src/vcs/VcsProcess.ts, the spawn uses timeout: input.timeoutMs with timeoutBehavior: "error", so the timeout kills the git process.
  • There is no cleanup of tmp_pack_* artifacts anywhere in apps/server/src when a fetch is killed/fails.

History (why this is filed fresh)

This is the same defect as #1965 (closed COMPLETED 2026-05-08). The mitigation that landed (#2605) only made the fetch interval configurable; it did not stop the leak. The actual cleanup fix, PR #2026, was closed unmerged on 2026-06-16 with: "Closing as obsolete because the Git utilities changed during the VCS rewrite. The tmp_pack behavior should be re-tested against the current GitVcsDriver before a fresh fix." This issue is that re-test: the bug is confirmed present in the post-rewrite driver (the VCS rewrite landed 2026-05-02 in #2435), shipped in v0.0.27, and still present on current main.

Suggested fix directions

  • Remove orphaned tmp_pack_* created by a status fetch when it is killed/fails (the intent of the abandoned Clean up leaked tmp_pack files after failed status refresh #2026), e.g. snapshot the pack dir before the fetch and prune new tmp_pack_* on non-success, or wrap the fetch so interruption triggers cleanup.
  • Prevent the perpetual-failure loop: don't hard-kill git index-pack, or use an adaptive/larger budget for the initial catch-up fetch, or back off / surface a "fetch couldn't complete" state instead of retrying the same doomed full fetch every cycle.

Impact

Blocks work completely — can silently fill the entire disk.

Version or commit

T3 Code 0.0.27 (also reproduced on main @ 4abf8b46c). VCS rewrite baseline: #2435.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions