Before submitting
Area
apps/server
Steps to reproduce
A repository whose remote was added with git remote add has no refs/remotes/origin/HEAD. Only git clone (or git remote set-head) creates it.
git init -q --bare -b main remote.git
git init -q -b main project && cd project
git commit -q --allow-empty -m init
git remote add origin ../remote.git
git push -q -u origin main
git symbolic-ref refs/remotes/origin/HEAD
# fatal: ref refs/remotes/origin/HEAD is not a symbolic ref (exit 128)
git show-ref --verify refs/remotes/origin/main
# <sha> refs/remotes/origin/main (the branch is there)
- Add
project as a T3 project.
- In Settings → Storage, turn on Delete unchanged worktrees and/or Delete merged worktrees.
- Start a thread in a new worktree, make no commits, and let it go idle.
- Run the cleanup.
Expected behavior
The worktree is removed with "No commits beyond the default branch." origin/main exists and the worktree's HEAD is an ancestor of it.
Actual behavior
Every worktree in the project is kept with "Default branch is unavailable." The unchanged and merged rules never run for that project, so only the inactivity rule can remove anything.
cleanWorktrees stops as soon as resolveDefaultBranchName returns null, and that function returns null whenever git symbolic-ref refs/remotes/<remote>/HEAD exits non-zero.
Other callers already handle the missing ref by falling back to main/master: resolveBaseBranchForNoUpstream, statusDetails, and branchPullRequest. Cleanup is the one that gives up.
The report line also gives the user nothing to act on: it names neither the remote nor the missing ref nor a remedy.
Evidence: the git commands above were run as written (git 2.43.0). The kept reason was observed on a real project in this state, where the cleanup kept 40 worktrees (about 32 GB); 43 of that project's worktrees have no commits beyond origin/main. I did not run a server against the throwaway repository above.
This is separate from #14843 and #17314. Those are about which remote is the base in a fork checkout, and #14843's reproduction has both remote HEAD refs set. This one happens with a single remote.
Suggested direction
When the remote HEAD is missing, probe main then master on the primary remote with the existing remoteBranchExists, as the callers above do. The fetch that follows already confirms the branch exists on the remote. Resolving the remote and default branch once per repository per sweep (today it is once per worktree) would keep the cost below what it is now.
If nothing resolves, a reason such as "Could not tell origin's default branch. Run git remote set-head origin --auto in the project." would be actionable.
Impact
Major degradation or frequent failure
Version or commit
main at f7664fd; observed on server nightly 0.0.46-nightly.20261010.2922
Environment
Linux, git 2.43.0
Workaround
Run git remote set-head origin --auto in the project checkout. Git 2.48 and later may create the ref on a plain git fetch, so older Git versions are the ones most exposed.
Before submitting
Area
apps/server
Steps to reproduce
A repository whose remote was added with
git remote addhas norefs/remotes/origin/HEAD. Onlygit clone(orgit remote set-head) creates it.projectas a T3 project.Expected behavior
The worktree is removed with "No commits beyond the default branch."
origin/mainexists and the worktree's HEAD is an ancestor of it.Actual behavior
Every worktree in the project is kept with "Default branch is unavailable." The unchanged and merged rules never run for that project, so only the inactivity rule can remove anything.
cleanWorktreesstops as soon asresolveDefaultBranchNamereturns null, and that function returns null whenevergit symbolic-ref refs/remotes/<remote>/HEADexits non-zero.Other callers already handle the missing ref by falling back to
main/master:resolveBaseBranchForNoUpstream,statusDetails, andbranchPullRequest. Cleanup is the one that gives up.The report line also gives the user nothing to act on: it names neither the remote nor the missing ref nor a remedy.
Evidence: the git commands above were run as written (git 2.43.0). The kept reason was observed on a real project in this state, where the cleanup kept 40 worktrees (about 32 GB); 43 of that project's worktrees have no commits beyond
origin/main. I did not run a server against the throwaway repository above.This is separate from #14843 and #17314. Those are about which remote is the base in a fork checkout, and #14843's reproduction has both remote HEAD refs set. This one happens with a single remote.
Suggested direction
When the remote HEAD is missing, probe
mainthenmasteron the primary remote with the existingremoteBranchExists, as the callers above do. The fetch that follows already confirms the branch exists on the remote. Resolving the remote and default branch once per repository per sweep (today it is once per worktree) would keep the cost below what it is now.If nothing resolves, a reason such as "Could not tell origin's default branch. Run
git remote set-head origin --autoin the project." would be actionable.Impact
Major degradation or frequent failure
Version or commit
mainat f7664fd; observed on server nightly 0.0.46-nightly.20261010.2922Environment
Linux, git 2.43.0
Workaround
Run
git remote set-head origin --autoin the project checkout. Git 2.48 and later may create the ref on a plaingit fetch, so older Git versions are the ones most exposed.