What
uploads@uploads fails to load after install. claude plugin list reports:
❯ uploads@uploads
Version: 0.2.0
Scope: user
Status: ✘ failed to load
Error: Hook load failed: Duplicate hooks file detected: ./hooks/hooks.json resolves to
already-loaded file ~/.claude/plugins/cache/uploads/uploads/0.2.0/hooks/hooks.json.
The standard hooks/hooks.json is loaded automatically, so manifest.hooks should only
reference additional hook files.
Error: Hook load failed: hooks: the file-path and array forms are not yet supported in a
marketplace entry. Define hooks in the plugin's own hooks/hooks.json (or its
plugin.json), or inline them here as an object mapping hook event names to matcher
arrays.
Impact: anyone installing the plugin gets no skills, no hooks, and no MCP server. The
plugin is effectively unusable via the marketplace path.
Cause
hooks is declared in two places, and hooks/hooks.json is already loaded automatically:
.claude-plugin/plugin.json → "hooks": "./hooks/hooks.json"
.claude-plugin/marketplace.json → the uploads entry also carries "hooks": "./hooks/hooks.json"
The second is additionally invalid: marketplace entries don't support the file-path form
for hooks, only an inline object.
Suggested fix
Drop the hooks key from both manifests and let hooks/hooks.json load by convention.
If an explicit declaration is wanted, keep it in plugin.json only — never in the
marketplace entry as a path.
Verification
After the change, claude plugin list should show uploads@uploads as enabled, and the
three bundled skills plus the hosted MCP server should be available in a fresh session.
Notes
Found while building the plugin eval suite under evals/. The suite itself loads the
plugin by path, so it works around this — but that means a green eval run does NOT prove
the marketplace install path is healthy. Worth a smoke check separate from the evals.
What
uploads@uploadsfails to load after install.claude plugin listreports:Impact: anyone installing the plugin gets no skills, no hooks, and no MCP server. The
plugin is effectively unusable via the marketplace path.
Cause
hooksis declared in two places, andhooks/hooks.jsonis already loaded automatically:.claude-plugin/plugin.json→"hooks": "./hooks/hooks.json".claude-plugin/marketplace.json→ theuploadsentry also carries"hooks": "./hooks/hooks.json"The second is additionally invalid: marketplace entries don't support the file-path form
for
hooks, only an inline object.Suggested fix
Drop the
hookskey from both manifests and lethooks/hooks.jsonload by convention.If an explicit declaration is wanted, keep it in
plugin.jsononly — never in themarketplace entry as a path.
Verification
After the change,
claude plugin listshould showuploads@uploadsas enabled, and thethree bundled skills plus the hosted MCP server should be available in a fresh session.
Notes
Found while building the plugin eval suite under
evals/. The suite itself loads theplugin by path, so it works around this — but that means a green eval run does NOT prove
the marketplace install path is healthy. Worth a smoke check separate from the evals.