Skip to content

claude-marketplace-json-valid

Marketplace.json must be valid JSON with required fields

Formerly known as marketplace-json-valid. The legacy name still works in configs, --rule/--skip-rule, suppression comments, and baselines.

Severity error (auto)
Autofix -
Since v0.1.0
Repo Types marketplace
Category Claude Code

Why

marketplace.json is the registry index for a plugin marketplace. If it contains invalid JSON or is missing required fields, tools that consume the marketplace cannot list or install plugins.

Examples

Bad:

{"plugins": []}

Good:

{
  "name": "my-marketplace",
  "description": "Internal plugin marketplace",
  "owner": {"name": "platform-team"},
  "plugins": []
}

How to fix

Fix the JSON syntax error or add the missing required fields reported in the violation message.

Plugin entries are also validated: every entry needs a unique name and a source. A string source is a path relative to the marketplace root — it should start with ./ and must not be an absolute path or escape the repository with ... An object source declares its type via the source field (github, url, git-subdir, npm, archive, or command) and must carry that type's required fields (repo, url, url + path, package, url, or command respectively). An archive source may also pin the download with an optional sha256 digest.

A command source runs through the platform shell and must satisfy Claude Code's reviewability constraints: printable ASCII, at most 500 characters, and no run of four spaces. Its optional timeout is a whole number from 1 through 600 and mode is copy or link. Download-and-execute, obfuscation, and other dangerous command patterns are errors.

When metadata.pluginRoot is set, it is prepended to relative sources, so bare names like "formatter" are valid and the ./ style nudge does not apply. The plugin root itself must be a string and, like sources, must not be an absolute path (values like /tmp/plugins are invalid) and must not escape the repository with ...

Escaping plugin directories

A plugins/* child whose resolved location falls outside the repository root — a symlink pointing at a sibling checkout, for example — is dropped from discovery, because autofix must never write outside the checkout. This rule reports the drop as a warning so the plugin cannot lose all rule coverage silently: move the plugin inside the repository (or vendor a copy) to restore coverage.

Codex marketplaces

A Codex catalog at .agents/plugins/marketplace.json is validated by codex-marketplace-json-valid, not by this rule: the two schemas disagree, and Codex's {"source": "local", "path": "./x"} would be reported here as an unknown source type on every entry. This rule raises neither "Marketplace file not found" nor an unknown-source error on a repository whose catalog is Codex's.

The legacy path .claude-plugin/marketplace.json, which Codex also reads for backward compatibility, stays with this rule. A Codex-schema catalog written to that path will be checked against the Claude schema and will report a missing owner and an unknown local source type — move it to .agents/plugins/marketplace.json.

Configuration

rules:
  claude-marketplace-json-valid:
    enabled: auto  # true | false | auto
    severity: error

Run skillsaw explain claude-marketplace-json-valid to see this documentation and the rule's effective configuration in your terminal.