git-subdir plugin sources fail on native Windows build - "git ... not on PATH" thrown without ever invoking git

Status Open
Reported on v2.1.226
Maintainer reply None cached
Activity 0 comments · opened Aug 10, 2026

Summary

On the native Windows build of Claude Code 2.1.226, installing any plugin whose marketplace source is git-subdir fails with:

git-subdir plugin source requires git to be installed and on PATH. Install git (version 2.25 or later for sparse-checkout cone mode) and try again.

git is installed, on PATH, and version 2.55.0.windows.3. The check appears to fail without executing git at all, so the message is misleading on both counts. This affects 85 of the plugins in claude-plugins-official; url- and github-source plugins install normally.

Environment

| | |
|---|---|
| Claude Code | 2.1.226, native build at %USERPROFILE%\.local\bin\claude.exe |
| OS | Windows 11 Pro 10.0.26200 |
| git | git version 2.55.0.windows.3 |
| git location | %LOCALAPPDATA%\Programs\Git\cmd\git.exe (user-scope Git for Windows) |
| Shell | PowerShell 7 |

Reproduction

claude plugin install miro@claude-plugins-official

Result: exit 1, error above. Same for stripe@claude-plugins-official, so it is not specific to one plugin. Reproduces both inside the JetBrains plugin and in a standalone terminal, and across a full restart.

Debug log

--debug-file output ends as follows. Note there are no intermediate lines between the temp-path message and the throw:

[DEBUG] Caching plugin from source: {"source":"git-subdir","url":"https://github.com/miroapp/miro-ai.git","path":"claude-plugins/miro","ref":"main","sha":"85c2c7347542b3ce185eb1d2793f8d79ad485c63"} to temporary path C:\Users\<user>\.claude\plugins\cache\temp_subdir_<ts>_<id>
[ERROR] Error: Error
    at rhd (B:/~BUN/root/src/entrypoints/cli.js:2545:54810)
    at async qSr (B:/~BUN/root/src/entrypoints/cli.js:2545:58349)
    at async GSr (B:/~BUN/root/src/entrypoints/cli.js:2545:26508)
    at async $e (B:/~BUN/root/src/entrypoints/cli.js:2545:35824)
    at async Yfn (B:/~BUN/root/src/entrypoints/cli.js:2545:36317)
    at async DNf (B:/~BUN/root/src/entrypoints/cli.js:22226:9329)
    at async ONf (B:/~BUN/root/src/entrypoints/cli.js:22228:8412)

The thrown error carries no message, and no temp_subdir_* directory is left behind, so it aborts before any clone work.

Evidence that git is never invoked

I compiled a git.exe shim that appends its argv to a log file and then delegates to the real git, and placed its directory first on PATH. It resolves correctly (Get-Command git points at the shim, and git --version through it returns the real version). During claude plugin install, the shim logged zero invocations.

Ruled out

| Hypothesis | Test | Result |
|---|---|---|
| git too old | git --version | 2.55.0.windows.3, floor is 2.25 |
| Not on PATH | Get-Command git, where.exe git | resolves fine |
| PATHEXT / .exe resolution | bare CreateProcess("git"), no shell | resolves fine |
| Looking for extensionless git | placed an extensionless git binary first on PATH | no change |
| PATH-sensitivity of any kind | removed git's directory from PATH entirely | identical error, so the check does not consult PATH |
| Git Bash not found | set CLAUDE_CODE_GIT_BASH_PATH to the user-scope bin\bash.exe; log confirms Using bash path: ... | no change |
| Stale process after mid-session auto-update | full restart | no change |
| IDE environment | standalone terminal vs JetBrains plugin | no change |
| git genuinely unable to do the work | ran the installer's own sequence by hand (below) | succeeds |

The equivalent manual sequence works

git clone --depth 1 --filter=tree:0 --no-checkout --branch main -- https://github.com/miroapp/miro-ai.git miro-clone
cd miro-clone
git sparse-checkout set --cone claude-plugins/miro
git checkout 85c2c7347542b3ce185eb1d2793f8d79ad485c63

Completes cleanly, including cone-mode sparse-checkout, and yields the expected plugin tree.

Expected

Either the git-subdir install succeeds, or the error names the real failure.

Minor, possibly related

Each failed attempt writes ~/.claude/settings.json twice — once adding the plugin entry, once rolling it back. Net effect is no change, but a failed install performing two atomic rewrites of user settings seems worth a look.

View original on GitHub ↗