Relative extraKnownMarketplaces directory paths resolve against the main checkout, not the active git worktree
Relative extraKnownMarketplaces directory paths resolve against the main checkout, not the active git worktree
Summary
A relative directory source in a project's .claude/settings.json extraKnownMarketplaces is resolved against the main checkout's root (the git common dir's parent) even when Claude Code is opened inside a git worktree. There is no way to make it resolve against the active worktree, because the path field does not support variable substitution (${CLAUDE_PROJECT_DIR}), and ${CLAUDE_PROJECT_DIR} points at the main checkout regardless.
This makes it impossible to develop an in-repo marketplace (or its plugins) on a feature branch inside a worktree and have Claude Code load that worktree's copy.
Environment
- Claude Code CLI (plugin marketplace feature)
- macOS
- Repo checked out via
git worktree(main checkout at/repo, worktree at/elsewhere/worktree)
Repro
- In a repo, add an in-repo marketplace at
marketplace/claude/.claude-plugin/marketplace.jsonand register it in the committed.claude/settings.json:
``json``
"extraKnownMarketplaces": {
"my-marketplace": {
"source": { "source": "directory", "path": "./marketplace/claude" }
}
}
- Commit these on a feature branch. Do not merge to the default branch, so the files do not exist on the main checkout.
- Create a git worktree for that branch and open Claude Code inside the worktree.
- Run
/plugin.
Expected
The relative path resolves against the worktree root (git rev-parse --show-toplevel), so <worktree>/marketplace/claude/.claude-plugin/marketplace.json is found and my-marketplace loads.
Actual
Marketplace file not found at <main-checkout>/marketplace/claude/.claude-plugin/marketplace.json
The relative path was resolved against <main-checkout> — i.e. the parent of git rev-parse --git-common-dir — where the branch's files do not exist. Note the extraKnownMarketplaces entry itself is correctly read from the worktree's .claude/settings.json (the main checkout has no such entry); only the path resolution uses the wrong base directory. So content and base directory disagree.
Impact
- You cannot iterate on an in-repo marketplace or its plugins from a worktree — Claude Code always loads the main checkout's version, so pre-merge changes and not-yet-merged marketplaces never load.
- Teams using worktree-based workflows (e.g. one worktree per branch) can't dogfood plugin changes before merge.
Workaround
Add an absolute path in the worktree's gitignored .claude/settings.local.json (or claude plugin marketplace add /abs/path/to/<worktree>/marketplace/claude). This is per-worktree and un-committable, so it doesn't scale as a shared registration.
Requests (either would resolve this)
- Resolve relative
extraKnownMarketplacesdirectorypaths against the active worktree root (show-toplevel) rather than the git common dir's parent — matching where the settings file that declared them was read from. - And/or support
${CLAUDE_PROJECT_DIR}(worktree-aware) expansion in thepathfield so a single committed registration can target the active checkout.
Docs to clarify either way: the settings reference and the worktrees page currently don't state how relative extraKnownMarketplaces paths resolve under worktrees.