claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[BUG] Plugin installPath incorrectly includes marketplace.json filename

Open ejc3 opened this issue 1 month ago • 2 comments

Description

When configuring a custom marketplace using a relative file path to marketplace.json, Claude Code incorrectly constructs the plugin's installPath by concatenating the full marketplace file path (including the .json filename) with the plugin source path, resulting in an invalid path and need to manually clear out cache.

Expected Behavior

The installPath should use the marketplace directory as the base, not the marketplace file path.

Expected:

"installPath": "../../.claude-plugin/plugins/project-shared-skills"

Actual Behavior

The installPath incorrectly includes marketplace.json as if it were a directory.

Actual:

"installPath": "../../.claude-plugin/marketplace.json/plugins/project-shared-skills"

Impact

  • Plugin shows as "Installed" in /plugin UI
  • Plugin fails to load with error: "Plugin 'project-shared-skills' not found in marketplace 'project-plugins'"
  • Skills, commands, and other plugin features are not available
  • Zero plugin skills/commands/agents loaded despite successful marketplace installation

Reproduction Steps

  1. Create a custom marketplace structure:
project/
├── .claude-plugin/
│   ├── marketplace.json
│   └── plugins/
│       └── project-shared-skills/
│           ├── .claude-plugin/
│           │   └── plugin.json
│           └── skills/
│               └── playwright/
│                   └── SKILL.md
└── apps/
    └── example/
        └── .claude/
            └── settings.json
  1. Configure marketplace in apps/example/.claude/settings.json:
{
  "extraKnownMarketplaces": {
    "project-plugins": {
      "source": { "source": "file", "path": "../../.claude-plugin/marketplace.json" }
    }
  },
  "enabledPlugins": {
    "project-shared-skills@project-plugins": true
  }
}
  1. Configure marketplace in project/.claude-plugin/marketplace.json:
{
  "name": "project-plugins",
  "owner": { "name": "Project DevTools" },
  "plugins": [
    {
      "name": "project-shared-skills",
      "source": "./plugins/project-shared-skills",
      "description": "Shared Skills for all project apps"
    }
  ]
}
  1. Start Claude Code from project/apps/example/ directory

  2. Check /plugin - marketplace shows as "Installed" but plugin fails to load

  3. Inspect ~/.claude/plugins/installed_plugins.json - observe malformed installPath

Environment

Claude Code Version

2.0.45

Platform

Google Vertex AI

Operating System

Other Linux

Terminal/Shell

Ghostty

Additional Context

  • Working directory: Subdirectory of repository (e.g., project/apps/example/)
  • Marketplace path: Relative path to parent directories (e.g., ../../.claude-plugin/marketplace.json)

Debug Log Evidence

From ~/.claude/debug/*.txt:

[DEBUG] Plugin loading errors: Plugin project-shared-skills not found in marketplace project-plugins
[DEBUG] Total plugin skills loaded: 0
[DEBUG] Total plugin commands loaded: 0

Root Cause Analysis

The plugin installation logic appears to concatenate:

  1. Marketplace source path: ../../.claude-plugin/marketplace.json
  2. Plugin source path from marketplace: ./plugins/project-shared-skills

Resulting in: ../../.claude-plugin/marketplace.json/plugins/project-shared-skills

The logic should strip the filename from the marketplace path or use the marketplace's directory as the base.

Workarounds Attempted

  • Using absolute paths (works but not portable across users/machines)
  • Moving plugins directory to different locations
  • Clearing cache files (known_marketplaces.json, installed_plugins.json)

Related Issues

This affects any setup where:

  • Custom marketplace is in a parent directory
  • Working directory is a subdirectory of the project
  • Relative paths are required for portability across team members

Suggested Fix

When constructing installPath, use path.dirname() on the marketplace file path before concatenating with the plugin source path, or recognize that marketplace paths ending in .json are files and should be treated as such.

ejc3 avatar Nov 08 '25 03:11 ejc3