[BUG] `/plugin marketplace add <local-path>` registers but plugin installs with 0 skills (workaround: pre-create symlink)

Resolved 💬 3 comments Opened Apr 30, 2026 by OleksandrSamygin Closed May 4, 2026

Title

[BUG] `/plugin marketplace add <local-path>` registers but plugin installs with 0 skills (workaround: pre-create symlink)

Body

Bug

When registering a marketplace from a local directory via the slash command:

/plugin marketplace add /Users/me/my-skills-marketplace

Claude Code reports Successfully added marketplace: <name> and creates ~/.claude/plugins/marketplaces/<name>/.... However, after /plugin install <plugin>@<name> and /reload-plugins, the plugin loads with 0 skills (reported as Reloaded: 1 plugin · 0 skills · N agents due to lazy-loaded skills being categorized as agents, but the user-visible result is "the skills do not appear").

The workaround is to pre-create the entry under ~/.claude/plugins/marketplaces/ as a symlink to the local path before running /plugin marketplace add. With the symlink in place, the same add + install + /reload-plugins flow loads all skills correctly.

This breaks the documented onboarding flow for any team that distributes a marketplace as a local directory (cloned via gh repo clone for private repos, for example), which is exactly the use case the CLI is designed to support.

Steps to reproduce

# 1. Clone a private marketplace repo locally
gh repo clone betterme-sandbox/pm-sm-ai-skills-marketplace ~/pm-sm-ai-skills-marketplace

# 2. Start Claude Code
claude

# 3. In the Claude Code REPL:
/plugin marketplace add ~/pm-sm-ai-skills-marketplace
# → "Successfully added marketplace: shared-skills"
# Files appear under ~/.claude/plugins/marketplaces/pm-sm-ai-skills-marketplace/

/plugin
# → Discover → shared-skills → "Install for you" → confirm
/reload-plugins
# → "Reloaded: 1 plugin · 0 skills · 0 agents"
# Skills do NOT appear when invoked: @shared-skills:<skill-name> → not found

Expected

The five skills declared in .claude-plugin/marketplace.json (shared/skills/*/SKILL.md) should be loaded and available for invocation, e.g. @shared-skills:jira-researcher.

Actual

Reloaded: 1 plugin · 0 skills · 0 agents — neither lazy-loaded skills nor anything else is registered. The marketplace files are physically present under ~/.claude/plugins/marketplaces/<name>/, but the loader does not discover them.

Workaround (works reliably)

Replace the auto-created marketplace directory with a symlink to the original local path before running /plugin marketplace add:

# After cloning, BEFORE /plugin marketplace add:
mkdir -p ~/.claude/plugins/marketplaces
ln -sfn ~/pm-sm-ai-skills-marketplace ~/.claude/plugins/marketplaces/pm-sm-ai-skills-marketplace
# Then in Claude Code:
/plugin marketplace add ~/pm-sm-ai-skills-marketplace
/plugin install shared-skills@pm-sm-ai-skills-marketplace
/reload-plugins
# → "Reloaded: 1 plugin · 0 skills · 5 agents" — all 5 skills now available

We've shipped this workaround in our team installer (install.sh creates the symlink before the user runs /plugin marketplace add). See INSTALL.md, step 2.

Hypothesis

The copy step from a local path likely produces a directory whose internal marketplace.json references plugin files via paths that do not resolve in the cache location (e.g., relative paths anchored to the original cwd). A symlink keeps every internal path resolvable to the original tree, which is why the workaround succeeds. Could not confirm without source access.

Why it matters

Distributing a Claude Code marketplace as a local directory is the canonical path for:

  • private/internal team marketplaces (cloned via gh repo clone, since curl raw... returns 404 for private repos)
  • on-premise / air-gapped setups
  • offline development

All of these silently fail with 0 skills unless every onboarding doc tells users to manually symlink — which most users will not do, so the result looks like "the marketplace doesn't work" rather than "there is a known workaround".

Environment

| | |
|---|---|
| Claude Code version | 2.1.123 |
| OS | macOS 14.4 (Sonoma, build 23E214) |
| Shell | zsh |
| Marketplace size | 5 skills, ~600 KB |
| Repro frequency | 100% (every fresh install without the symlink workaround) |

Suggested fixes (in order of preference)

  1. Best: make /plugin marketplace add <local-path> symlink the directory by default (or behind a --symlink flag), instead of copying. Local paths are inherently mutable; copy semantics surprise users who edit the source tree and expect changes to reflect.
  2. If symlink-by-default is too aggressive, at minimum fix the copy so the resulting cache structure resolves the same way the source does.
  3. Print a non-zero exit code or a [WARN] line when marketplace add succeeds but the loader cannot discover any skills — current "Successfully added" + "0 skills" is silent failure.

Related

  • #36655 — marketplace add not registered in known_marketplaces.json (different surface, same family of "registered but not usable")
  • #52147 — local plugin installation in desktop app (feature request, related)
  • #41392 — symlinks inside plugin dirs not dereferenced (related but distinct: that is inside a plugin, this is the marketplace-level path)

Happy to provide more diagnostics (a ~/.claude/plugins/marketplaces/<name>/ listing before/after, debug logs) if helpful.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗