Skip to content

[Bug]: UI pull reports failure after a successful fast-forward when Git output exceeds 1 MB #17358

Description

@jgoyvaerts

Before submitting

Area

apps/server, surfaced by the desktop/web Git pull action.

Steps to reproduce

  1. Open a Git repository whose current branch tracks an upstream and can fast-forward across a large update.
  2. Use the Pull action in the top-right Git controls.
  3. If Git's output exceeds 1,000,000 bytes on stdout or stderr, T3 reports the pull as failed. The repository may already have advanced before the output collector fails.
  4. Check HEAD and the reflog to compare the reported failure with the repository's actual state.

Observed on the t3code repository while pulling main from 2188bdd8b5 to d81afa0a6f. This update touched 13,764 files.

Expected behavior

A successful Git pull should be reported as successful even if its informational output is large. Keep output buffering bounded, but wait for Git's exit status and refresh the repository state rather than treating truncated informational output as command failure.

Actual behavior

The UI reported:

Git command failed in GitVcsDriver.pullCurrentBranch.pull (<repo>): Git output exceeded 1000000 bytes and was truncated.

The same attempt had already fast-forwarded the repository. HEAD subsequently matched the fetched origin/main, and the working tree was clean.

Impact

Minor bug or occasional failure. Large updates produce a misleading failure after changing the repository, so the user cannot rely on the UI result to know whether the pull applied.

Version or commit

Installed Nightly app metadata: 0.0.46-nightly.20261007.2774.
Source inspected: main @ d81afa0a6f403bd6e5562ffcee2484089a1fdc3f.

Environment

macOS 26.6.2, Apple Silicon (arm64), Git 2.48.1. Observed through the desktop UI.

Evidence

The persisted UI/server trace records the failing pull from 2026-10-08 20:20:21 to 20:20:38 (UTC-03:00). The Git reflog records the fast-forward during that same interval:

d81afa0a6f HEAD@{2026-10-08 20:20:37 -0300} pull --ff-only: Fast-forward

Read-only reconstruction of the update's stat and file summary:

git diff --stat --summary 2188bdd8b5 d81afa0a6f

Measured stdout: 1,549,511 bytes, across 21,293 lines. This reconstructed summary is a likely source of the overflow; the original raw stdout/stderr was not retained in the trace.

Code investigation

At the inspected commit:

  • pullCurrentBranch runs git pull --ff-only without enabling truncation. The command's output is not used to determine the pull result; the subsequent before/after HEAD comparison is.
  • execute defaults to a 1,000,000-byte cap and appendTruncationMarker: false.
  • collectOutput raises GitCommandError when that cap is exceeded. An existing truncation path can drain further output while retaining only the bounded prefix.

A focused fix could use that bounded truncation path for pull, preserve nonzero-exit handling, and test oversized output with both successful and failed Git exits.

Workaround and verification limits

For this incident, no retry was needed: checking the reflog, HEAD, upstream, and working tree established that the update applied.

Investigation was read-only. No second pull, backend restart, or browser reproduction was performed. Installed app metadata was read, but the exact running bundle was not independently identified. Local paths are redacted, and no raw private logs are attached.

Activity

  1. juliusmarminge commented on Oct 8, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Thanks for the careful write-up and the 2188bdd8b5 → d81afa0a6f evidence — that lines up with what main is doing today (d81afa0a6f).

    What looks wrong

    pullCurrentBranch runs git pull --ff-only with no truncation options, then decides success from a before/after HEAD comparison. The command’s stdout/stderr are not used for that result.

    execute still defaults to a 1,000,000-byte cap (DEFAULT_MAX_OUTPUT_BYTES) with appendTruncationMarker defaulting to false. In that mode, collectOutput fails with Git output exceeded … bytes and was truncated. instead of draining and keeping a bounded prefix.

    So a pull that has already fast-forwarded can still surface as a UI failure once Git’s informational output (likely the default pull/merge diffstat) crosses the cap — matching the error you saw.

    git pull --ff-only is also the path used by automatic pull:

    I did not re-run a large pull here; the notes above come from reading main plus your report.

    Precedents / related

    Callers that already opt into the soft truncate path via appendTruncationMarker: true include prepareCommitContext (staged patch), readRangeContext (log / --stat / patch), and review-diff patch reads in the same driver — useful patterns to copy for pull, where the buffered text is not needed for the return value.

    There does not appear to be a --no-stat usage under apps/server today. Several fetch invocations do pass --quiet, but pull does not.

    Related (large Git output / same class of cap), not the same surface:

    • #413 / #567 — large diff paths for commit/push/PR / checkpoint (closed)

    No open duplicate or open PR that looks like it already fixes this pull path turned up on search. Main at d81afa0a6f still matches the behavior you inspected.

    Likely minimal fix (hedged)

    Smallest change that matches existing patterns: pass appendTruncationMarker: true on the pullCurrentBranch executeGit call so oversized informational output is drained/truncated instead of failing the Effect, while still failing on a non-zero Git exit. Optionally (or also) add --no-stat / -q to git pull --ff-only so large updates do not emit a multi‑MB diffstat in the first place — complementary, and closer to how fetch already stays quiet.

    A test that simulates oversized stdout with both exit 0 and non-zero would help lock the “success vs real failure” split.

  2. added
    bugSomething is broken or behaving incorrectly.
    via-triageFiled through npx t3 triage
    on Oct 8, 2026
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