CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE still breaks fresh marketplace install on 2.1.169 (ref #43929)
Preflight
Searching surfaced #43929, which describes this exact bug; it was auto-closed as stale (last reproduced on 2.1.92) and the closing comment invited a fresh issue if still relevant. I confirm it still reproduces on 2.1.169.
What's Wrong?
When CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1 is set, every fresh /plugin marketplace add <git source> fails immediately with Marketplace file not found at .../plugins/marketplaces/temp_<epoch>/.claude-plugin/marketplace.json, and every startup marketplace refresh logs git pull failed, keeping existing clone. Existing marketplaces keep working (their directory already exists); only fresh installs and refreshes break.
What Should Happen?
For a fresh install (target directory absent) the clone should always proceed. KEEP_MARKETPLACE_ON_FAILURE should only apply when the marketplace directory already exists.
Steps to Reproduce
- Set
CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1in the environment. /plugin marketplace add https://github.com/<any/public-repo>.git- Immediate
Marketplace file not found at .../temp_<epoch>/.claude-plugin/marketplace.json; no clone progress, the temp directory is never populated.
Error Messages/Logs (--debug)
[DEBUG] git pull: cwd=.../plugins/marketplaces/temp_<epoch> ref=default
[WARN] git pull failed, keeping existing clone (CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE):
[ERROR] [reconcile] failed to update marketplace '<name>': Marketplace file not found at .../temp_<epoch>/.claude-plugin/marketplace.json
The git pull fails in ~20 ms with empty stderr — it runs against a non-existent temp directory, so it never touches the network. A plain git clone of the same repo at the shell succeeds.
Root Cause (confirms #43929 on 2.1.169)
The sparse-checkout reconcile returns {code:0} when the target directory doesn't exist, so git pull is attempted on a non-existent directory and fails instantly; the KEEP_MARKETPLACE_ON_FAILURE guard then early-returns without ever cloning. It can't distinguish "pull failed on an existing clone" from "directory doesn't exist yet", so the fallback clone never runs.
Suggested Fix
Gate the guard on directory existence — if (KEEP && directoryExists(target)) return; — or have the sparse-checkout reconcile return {code:1} when the target directory is absent so it goes straight to clone (as proposed in #43929).
Workaround
Unset CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE — then fresh installs clone normally.
Environment
- Claude Code version: 2.1.169
- Platform: Linux (WSL2)
- Shell: zsh
- Regression: reported on 2.1.92 (#43929), still present on 2.1.169