[BUG] Systemic inconsistency: git-subdir source type supported by runtime and used in official marketplace, but rejected by schema validator

Resolved 💬 3 comments Opened Mar 21, 2026 by alaslibress Closed Mar 21, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

The plugin marketplace schema validator rejects "source": "git-subdir" as an invalid source type, but this type is:

  1. Used in the official marketplaceclaude-plugins-official defines "source": "git-subdir" for plugins like Railway and Semgrep
  2. Supported by the runtime — the changelog includes "Fixed git-subdir plugins at different subdirectories of the same monorepo commit colliding in the plugin cache", proving runtime handling exists
  3. Referenced in documentation — community and derived docs list git-subdir alongside url and relative paths as valid source formats

| Layer | git-subdir status |
|-------|-------------------|
| Schema validator | Rejects it |
| Runtime / cache engine | Supports it |
| Official marketplace | Uses it |

This inconsistency creates a cascade of failures for third-party marketplace authors:

Stage 1 — Author uses "source": "git-subdir" (copying the pattern from claude-plugins-official). Validator rejects it. Entire marketplace fails to load — not just the invalid entry.

Stage 2 — Author migrates to "source": {"source": "url", ...} to work around Stage 1. This passes schema validation but triggers #26555: category and source fields from the marketplace entry leak into the cached plugin.json, causing a second validation error (Unrecognized keys: "category", "source").

Stage 3 — The only format that survives both validators is a relative path string ("source": "./path/to/plugin"), but this only works when the plugin lives in the same repository. For plugins in external repositories (the primary use case for git-subdir), there is no reliable path.

Real-world impact: Gentleman-Programming/engram (1,500+ stars) had its Claude Code marketplace plugin broken for all users. Two separate fix attempts (PR #71, PR #86) by different contributors failed because both correctly fixed the key name but not the value — the git-subdir format appeared legitimate since Anthropic's own marketplace uses it. The project has now migrated to relative paths as a workaround.

Related issues: #33739 reports git-subdir failure for Semgrep, #34567 reports validation errors on v2.1.58, #26555 reports the cache leak. This issue connects all three as stages of a single systemic problem rather than isolated bugs.

What Should Happen?

Two changes, ideally both:

1. Accept git-subdir in the schema validator — The runtime already handles it (the cache collision fix proves this). The official marketplace already uses it. The validator should match.

2. Graceful degradation for invalid plugin entries — A single invalid entry currently breaks the entire marketplace catalog (~58 plugins become unavailable when one fails). The validator should skip or warn on individual invalid entries rather than failing the full load.

Error Messages/Logs

Failed to load marketplace "engram" from source (github):
Failed to parse marketplace file at
~/.claude/plugins/marketplaces/gentleman-programming-engram/.claude-plugin/marketplace.json:
Invalid schema: plugins.0.source: Invalid input

 
The same error pattern for the official marketplace:
 

Failed to load all marketplaces. Errors:
claude-plugins-official: Invalid schema:
plugins.56.source: Invalid input,
plugins.63.source: Invalid input,
plugins.67.source: Invalid input,
plugins.71.source: Invalid input,
plugins.72.source: Invalid input

Steps to Reproduce

Minimal reproduction — no external dependencies:

  1. Create a test marketplace:
mkdir -p /tmp/test-mkt/.claude-plugin
cat > /tmp/test-mkt/.claude-plugin/marketplace.json << 'EOF'
{
  "name": "test-marketplace",
  "owner": { "name": "Test" },
  "plugins": [{
    "name": "test-plugin",
    "description": "Minimal git-subdir reproduction",
    "source": {
      "source": "git-subdir",
      "url": "https://github.com/anthropics/claude-code.git",
      "path": "plugins/example-plugin"
    }
  }]
}
EOF
  1. Attempt to add the marketplace:
claude plugin marketplace add /tmp/test-mkt
  1. Observe the error: Invalid schema: plugins.0.source: Invalid input
  1. For comparison, the same plugin with a relative path works:
"source": "./plugins/example-plugin"

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.81 (Claude Code)

Platform

Anthropic API

Operating System

Other Linux

Terminal/Shell

Other

Additional Information

Evidence of runtime support despite validator rejection:

The Claude Code changelog entry "Fixed git-subdir plugins at different subdirectories of the same monorepo commit colliding in the plugin cache" confirms that the runtime has code to handle git-subdir sources. The validator rejects the format before that code can execute, creating a dead code path.

Third-party ecosystem impact:

The inconsistency between the official marketplace's usage of git-subdir and the validator's rejection of it has a multiplier effect: third-party authors copy the pattern from claude-plugins-official (the most authoritative reference), their marketplace breaks, and debugging leads them through a series of false fixes because the format looks correct. In the case of Engram, two independent contributors submitted fixes that addressed the wrong layer of the problem.

Cascade documentation:

| Stage | What happens | Related issue |
|-------|-------------|---------------|
| 1 | git-subdir rejected by schema validator | #33739, #34567 |
| 2 | Migration to url object triggers cache leak of category/source into plugin.json | #26555 |
| 3 | Only relative paths survive both validators (but only work for same-repo plugins) | (this issue) |

Repository demonstrating the issue: Gentleman-Programming/engram — see .claude-plugin/marketplace.json history for the two failed fix attempts and the final migration to relative paths.

View original on GitHub ↗

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