[BUG] origin remote URL corruption via GIT_COMMON_DIR + rbs/ruby-lsp in devcontainer

Status Fixed / completed
Maintainer reply None cached
Activity 6 comments · opened Apr 20, 2026 · closed Apr 21, 2026

Summary

The repository's origin remote was corrupted: the URL changed from
git@github.com:org/myrepo.git to
https://github.com/ruby/gem_rbs_collection.git, and partial clone settings
(promisor = true, partialclonefilter = blob:none) were injected along with
duplicate fetch entries. As a result, git push failed with "Permission denied"
and git fetch was pulling branches from an unrelated repository.

---

Timeline

| Date/Time | Event |
|---|---|
| 2026-04-17 ~16:46 UTC | Claude Code created branch worktree-user+test from origin/main via its isolation: "worktree" feature |
| 2026-04-17 ~17:03 UTC | Commit on worktree-user+test: "dev container compatibility for git worktree" |
| 2026-04-20 12:01:07 UTC | User manually created worktree test: git worktree add -b test ../.claude/worktrees/test user/my-feature |
| 2026-04-20 12:09:31 UTC | .git/config modified: origin URL replaced, partial clone config injected, refspecs duplicated |
| 2026-04-20 12:10:09 UTC | FETCH_HEAD updated with branches from ruby/gem_rbs_collection |

---

Evidence

Resulting .git/config remote section:

[remote "origin"]
    url = https://github.com/ruby/gem_rbs_collection.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    fetch = +refs/heads/*:refs/remotes/origin/*
    promisor = true
    partialclonefilter = blob:none
    fetch = +refs/heads/*:refs/remotes/origin/*
    fetch = +refs/heads/*:refs/remotes/origin/*
    fetch = +refs/heads/*:refs/remotes/origin/*

The config also contains a [branch "worktree-user+test"] entry with
remote = origin and merge = refs/heads/main, auto-generated by Claude Code.

Full corrupted .git/config at time of detection:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
    hooksPath = /Users/user/projects/myrepo/.git/hooks
[remote "origin"]
    url = https://github.com/ruby/gem_rbs_collection.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    fetch = +refs/heads/*:refs/remotes/origin/*
    promisor = true
    partialclonefilter = blob:none
    fetch = +refs/heads/*:refs/remotes/origin/*
    fetch = +refs/heads/*:refs/remotes/origin/*
    fetch = +refs/heads/*:refs/remotes/origin/*
...
[branch "worktree-user+test"]
    remote = origin
    merge = refs/heads/main

---

Root cause (hypothesis)

Evidence strongly points to Claude Code's isolation: "worktree" feature as
the origin of the corruption. A git bug cannot be ruled out entirely, but is
considered unlikely.

Evidence pointing to Claude Code

  • The branch worktree-user+test is clearly auto-generated — the user created

-b test, not that name. It was created on April 17 from origin/main and
has a commit authored by Claude Code.

  • The EnterWorktree tool is available in Claude Code sessions and is part of the

isolation: "worktree" implementation.

  • The promisor = true and partialclonefilter = blob:none settings are

characteristics of a partial clone — a technique Claude Code likely uses to
create lightweight worktrees.

Probable sequence

  1. April 17: Claude Code ran an agent with isolation: "worktree", which

invoked EnterWorktree. As part of its fetch mechanism, it configured origin
with the wrong URL (gem_rbs_collection) and partial clone parameters, and
created the worktree-user+test branch.

  1. April 20, 12:01: The user manually created the test worktree.

git worktree add itself does not modify remotes.

  1. April 20, 12:09–12:10: A subsequent operation (possibly Claude Code

re-invoking EnterWorktree, a fetch triggered by a devcontainer init script,
or an IDE running git operations when opening the devcontainer) ran
git fetch origin against the already-corrupted remote, updating FETCH_HEAD
with gem_rbs_collection branches and consolidating the corruption in the
config.

Why gem_rbs_collection

Unknown. Possible causes:

  • Bug in Claude Code when resolving the remote URL during worktree creation.
  • Confusion between the project remote and the gem_rbs_collection repository,

which is a Ruby RBS type definitions collection — a dev dependency of the
project's Ruby stack.

Ruled out: git bug

git worktree add is a local operation that does not modify remotes. All
repository hooks are .sample files (inactive). git 2.50.1 (Apple Git-155) has
no known bugs related to this operation.

---

Impact

  • git push failed with remote: Permission to ruby/gem_rbs_collection.git denied to username.
  • git fetch was pulling branches from an unrelated external repository.
  • No commits or project data were lost (local history was not affected).

---

Fix

Restore [remote "origin"] in .git/config:

[remote "origin"]
    url = git@github.com:org/myrepo.git
    fetch = +refs/heads/*:refs/remotes/origin/*

---

Environment

  • OS: macOS Darwin 25.4.0
  • git: 2.50.1 (Apple Git-155)
  • Claude Code: CLI, model claude-sonnet-4-6
  • Project structure: monorepo with git worktrees stored under .claude/worktrees/
  • Active hooks: none (all .sample)

---

Related issues

  • anthropics/claude-code#45201 — isolation: "worktree" also modifies .git/config (sets extensions.worktreeConfig), confirming the feature writes to the shared config as a side effect.
  • anthropics/claude-code#47266 — concurrent worktree creation causes .git/config lock collisions, further evidence that the feature performs direct writes to .git/config.

View original on GitHub ↗

6 Comments

github-actions[bot] · 4 months ago

Found 1 possible duplicate issue:

  1. https://github.com/anthropics/claude-code/issues/32793

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

0xbrainkid · 4 months ago

If isolation: "worktree" can mutate the main repository .git/config, replace origin with an unrelated upstream, and inject partial-clone settings/refspec drift, then this is not a normal worktree bug, it is repository-identity corruption.

The word "isolation" is doing a lot of work here, and the current behavior appears to violate it. A feature intended to safely compartmentalize work should never cross the boundary and rewrite core remote identity for the parent repo.

That is especially serious because the blast radius is operational, not cosmetic:

  • pushes fail
  • fetches target the wrong repository
  • remote trust assumptions are broken
  • the user now has to audit .git/config itself

Once a tool can silently mutate repo identity metadata, users have to defend against the tool instead of relying on it. This needs very strong containment guarantees.

stormwatch · 4 months ago

Possible duplicate / same root cause as #32793

After running the reproduction steps (see https://github.com/stormwatch/worktree-bug-reproduction), the remote URL corruption was not reproduced with a local filesystem remote. Only a hooksPath entry was added to .git/config.

While investigating, we found #32793 which describes an identical corruption pattern:

  • A Claude Code internal operation runs git remote set-url origin <url> without git -C /path/to/target/
  • git walks up the directory tree and finds the user's project .git
  • The user's origin remote gets overwritten with the URL intended for Claude Code's internal clone
  • Duplicate fetch refspecs are injected as a side effect

In #32793 the trigger is claude install and the URL is anthropics/claude-plugins-official. In our case the URL is ruby/gem_rbs_collection — a Ruby RBS type definitions repository. This suggests the marketplace updater was trying to update a Ruby-related plugin and ran the git commands without -C, landing on the user's project repo instead.

The isolation: "worktree" attribution in this issue may be incorrect. The auto-generated worktree-user+test branch was created in the same timeframe but is likely unrelated to the remote corruption. The actual culprit is probably the same missing -C flag as in #32793, triggered by a different marketplace update.

Leaving it to Anthropic to decide whether to close this as a duplicate of #32793 or track it separately as a distinct instance of the same root cause.

stormwatch · 4 months ago

I'm using Claude Code itself to look for the root cause. Its latest finding seems to suggest that in my case the issue is caused by the rbs gem:
https://github.com/ruby/rbs/blob/e6601ef71400dd016987abc55d501d702e218256/lib/rbs/collection/sources/git.rb#L138-L145

And the sh! method defined as:
https://github.com/ruby/rbs/blob/e6601ef71400dd016987abc55d501d702e218256/lib/rbs/collection/sources/git.rb#L198-L206

when chdir: nil is passed, the .compact removes the nil key, leaving {} — no directory. The git clone --filter=blob:none is run from the CWD of the process (the project directory).

stormwatch · 4 months ago

Looking at the weird dev container setup that I was trying to use, (which messed up with GIT_COMMON_DIR and other environment variables), together with what I said in my previous message, I was able to reproduce previously unforeseen consequences to their interaction; which are not related to claude code. I think it is best to close this one.

In https://github.com/anthropics/claude-code/issues/32793 I see a similar symptom but a different mechanism. Claude Code marketplace updater runs git remote set-url without -C.

github-actions[bot] · 3 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.