[Desktop] Managed thread-owned worktree checks out local main during cleanup
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Summary
Codex Desktop managed worktrees can repeatedly check out the repository's shared local default branch during agent merge/cleanup. The worktree remains registered and thread-owned afterward, so the user's canonical checkout can no longer switch to main:
fatal: 'main' is already used by worktree at '/Users/<user>/.codex/worktrees/<id>/<repo>'
This is distinct from stale/unregistered worktree metadata: the conflicting worktree still exists, is registered by Git, and contains Codex thread ownership metadata.
Environment
- macOS
- ChatGPT Desktop 26.825.51511 (build 7377)
- Codex CLI 0.151.0
- Apple Git 2.50.1
Evidence
The managed worktree was initially created detached, as expected. Its Git reflog later showed the agent repeatedly performing this sequence during merge/cleanup:
checkout: moving from codex/<task-branch> to main
pull --ff-only origin main
After completion the clean managed worktree remained attached to local main. A subsequent git switch main in the canonical checkout failed because linked worktrees intentionally enforce exclusive local-branch ownership.
The problem has recurred across repositories, so it is not specific to one repository's hooks or configuration.
Expected behavior
Codex-managed linked worktrees should never attach the shared local default branch during setup, synchronization, merge, or cleanup.
After a task branch is merged, the managed worktree should either:
- remain detached at the current remote-tracking default commit (for example
origin/main), or - be safely reclaimed/removed when the task lifecycle permits.
The UI should also make the owning task discoverable when a managed worktree blocks a branch.
Actual behavior
A thread-owned managed worktree persists and owns local main, blocking ordinary branch switching in the canonical checkout.
Safe workaround
After confirming the managed worktree is clean and identifying its owning task:
git -C ~/.codex/worktrees/<id>/<repo> switch --detach HEAD
A structural local mitigation is to keep the canonical checkout permanently on main, forcing task work into uniquely named branches or detached managed worktrees.
Related issues
This appears related to worktree lifecycle/retention reports such as #14575 and #35383, and worktree/UI binding reports such as #28743 and #37591, but the key distinction here is that the managed worktree is not merely stale: Codex actively switched a live thread-owned worktree onto the shared default branch during cleanup.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing Codex Desktop/CLI worktree lifecycle handling during agent merge and cleanup, using the reported reflog sequence and the linked-worktree behavior as the reproduction. Verify that a managed worktree does not attach local main, and that cleanup either leaves it detached at the remote-tracking default commit or safely removes it. Check that the owning task is discoverable when the worktree blocks a branch.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, rust
- Domain
- desktop, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100