Skip to content

A Ticket's Run fails on a fetch race newer git words differently, and its cause shows only git's banner line #309

Closed

Description

@JacobStephens2

This was generated by AI during triage.

What happened

A Spec run ended as a Failed spec run with Tickets not done: #1348, #1349. Neither Ticket had done any work: both Runs failed three seconds after starting, before creating a worktree or starting a session. The other three Tickets started at the same moment landed normally.

One Ticket blocked the other five. When it merged into the Spec branch, the five unblocked Tickets started at once, and each Ticket's Run fetched the Spec branch in the shared Launch directory. Every fetch tried to move the same remote-tracking ref from the same old commit to the same new one. One won; two of the others failed:

12:43:36 starting #1348
12:43:36 starting #1349
12:43:36 starting #1350
12:43:36 starting #1351
12:43:36 starting #1352
12:43:39 #1349: git fetch origin issue-1346 failed: From https://github.com/<owner>/<repo>
12:43:39 #1349: * branch                issue-1346 -> FETCH_HEAD
12:43:39 #1349: 93d814703..8cf48f061  issue-1346 -> origin/issue-1346
12:43:39 #1349: error: fetching ref refs/remotes/origin/issue-1346 failed: incorrect old value provided
12:43:39 #1349 failed

Two defects

1. The race is not retried. thirdshift already retries a git command that fails because another git moved a ref it was updating, but it recognises that only by git's older wording (cannot lock ref … but expected). git 2.52 reports the same race as fetching ref <ref> failed: incorrect old value provided, which is not recognised, so the fetch fails outright. A second attempt would have been a no-op and succeeded.

2. The reported cause hides the error. The Ticket's line in the end-of-run summary, the Tickets checklist and the Run notification kept only the first line of the cause:

#1348 failed: git fetch origin issue-1346 failed: From https://github.com/<owner>/<repo>

For a failed git command the first line of stderr is often a banner like From …; git's own error: line came last and was dropped.

Reproduction

git 2.52.0. In a clone, with origin's branch spec one commit ahead of the clone's origin/spec, run five git fetch origin spec at once in that clone. Over 40 rounds, four of the five failed every time, each with the stderr above. On the real run, network timing let three of five through.

Impact

Any Spec where one Ticket blocks two or more others hits this when the blocker lands, on a host with a recent git. The same unlocked fetches of a shared remote-tracking ref also happen later in a Run, from each Run's worktree, where losing the race would fail a Run whose session had already finished.

Activity

  1. JacobStephens2 commented on Oct 2, 2026

    @JacobStephens2
    OwnerAuthor

    This was generated by AI during triage.

    Agent Brief

    Category: bug
    Summary: Retry a git command that loses a ref-update race as newer git words it, and report a failed git command's cause by git's own error line

    Current behavior:
    Git::run runs a failed command again, for a bounded time, while its stderr says another git holds a lock file or moved a ref between reading and updating it. That check (held_lock) knows the race only as cannot lock ref … but expected. git 2.52 reports it as error: fetching ref refs/remotes/origin/<branch> failed: incorrect old value provided, so concurrent fetches of one branch from Runs sharing a Launch directory fail instead of being retried. In a Spec run this fails Tickets that had not started any work.

    Separately, a failed git command's error is git <args> failed: followed by the last lines of its stderr, then stdout, in the order git wrote them. A child Run's cause is read back by what started it as its first line only, and that line is what the Ticket's summary line, the Tickets checklist and the Run notification show. For a failed fetch the first line is the From <url> banner, and git's error: line, which says what went wrong, is dropped.

    Desired behavior:

    • A git command that fails with incorrect old value provided on stderr is treated like the other cases of a ref another git moved meanwhile: run again within the same bounded wait, and failing as now only if it still fails once the wait is over. The older wordings keep being recognised.
    • The first line of a failed git command's error names what git said went wrong: when stderr has lines starting error: or fatal:, the first such line follows git <args> failed: on the first line of the message. Nothing git wrote is lost: the rest of the reported lines still follow, within the existing limit on how many lines are kept. A failure with no such line, such as a hook's explanation on stdout or no output at all, reads as it does today.

    Key interfaces:

    • Git::run: its retry condition and the message it fails with. Its signature does not change.
    • held_lock: recognises the new wording as well.
    • The reading back of a child Run's ending (ChildFailure::cause, "the first line of its cause") is unchanged; the fix is that a git failure's first line is now the informative one.

    Acceptance criteria:

    • A test shows a git command whose first attempt fails with error: fetching ref refs/remotes/origin/main failed: incorrect old value provided on stderr is run again and succeeds, alongside the existing test for the cannot lock ref … but expected wording
    • A test shows a failed git command whose stderr is a From … banner, ref lines, then an error: line produces a message whose first line is git <args> failed: error: …, with the other lines still present
    • The existing tests of a failure's message still pass: a hook's output and git's own error both appear, stdout is included, only the last lines of a stream are kept, and a failure with no output says only that git failed
    • Given that message as a child Run's cause, a Ticket's line reads #<n> failed: git fetch origin <branch> failed: error: …
    • cargo test and cargo clippy pass

    Out of scope:

  2. added
    bugSomething isn't working
    ready-for-agentFully specified, ready for an AFK agent
    in-progressA Claim: thirdshift has taken this issue
    and removed
    ready-for-agentFully specified, ready for an AFK agent
    on Oct 2, 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 isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions