fix(container): trust bind-mounted repos despite the VirtioFS uid flap - #177
Merged
Merged
Conversation
Docker Desktop's VirtioFS intermittently stats host bind mounts as uid 0 instead of the host uid. Git checks the worktree directory's owner, so on those calls it aborts with "detected dubious ownership" and the whole command fails. Measured 15/15 correlation between a non-host uid on the worktree dir and the git failure, at rates between 33% and 58% depending on the window. The flap hits the worktree dir far more often than .git, so probing .git alone shows a stable owner and the failures look like a ghost. Agents have been aborting scheduled runs over it rather than act on unreliable reads. Set safe.directory to * at the system level in the agent image. safe.directory is additive across config scopes, so a system entry survives the host ~/.gitconfig that gets mounted over the agent's global config, and nothing on the host is modified. The trust check buys nothing in this container anyway: single-tenant, permissions already skipped, and only the user's own directories are ever mounted. Verified in a live flap window: 40/40 plain git calls failed while 40/40 with the system entry succeeded. Also confirmed the RUN line writes and reads back on the real golang:1.27 base image. Ships with a refreshContainerFiles migration so existing installs get the updated Dockerfile before their next image rebuild, and repins the guard digest added alongside the previous refresh.
radutopala
enabled auto-merge (rebase)
August 27, 2026 07:40
radutopala
disabled auto-merge
August 27, 2026 07:46
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Docker Desktop's VirtioFS intermittently stats host bind mounts as uid 0 instead of the host uid. Git checks the worktree directory's owner, so on those calls it aborts:
Measured a 15/15 correlation inside an agent container — git fails on exactly the probes where the worktree dir stats as 0, succeeds when it stats as the host uid:
Observed failure rates ran 33–58% depending on the window. It affects every VirtioFS bind mount; the ext4 named cache volumes never flap.
The flap hits the worktree dir far more often than
.git, so probing.gitalone shows a stable owner and the failures look like a ghost with no cause. Scheduled agent runs have been aborting over it — correctly refusing to make destructive decisions whengit worktree list,git branch, andgh pr listcan't be trusted to agree.To be clear about what this is not: the entrypoint's chown loop never touches project directories.
CHOWN_PATHSonly covers the cache volumes (.npm,.local/share/uv,.cache,/go,.ollama,.claude.json), and those are ext4, not VirtioFS.Fix
Set
safe.directory = *at the system level in the agent image.safe.directoryis additive across config scopes, so a system entry survives the host~/.gitconfigthat gets mounted over the agent's global config./etc/gitconfigis container-local — nothing on the host is modified. Writing the user's~/.gitconfigwould not be acceptable, since it's a bind mount of their real file.Verification
RUNline writes and reads back on the realgolang:1.27base image.make coverage-check— 100.0%make lint-go— 0 issuesMigration
Ships a
refreshContainerFilesmigration so existing installs get the updated Dockerfile before their next image rebuild, and repins the digest guard added with the previous refresh — which is what caught the need for this migration in the first place.