[BUG] Cowork marketplace sync rejects a plugin with `source: "./"` and no plugin.json that the CLI validates and installs fine; Desktop UI hides the real error
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?
A marketplace whose single plugin entry uses "source": "./" (plugin = marketplace root, skills auto-discovered from ./skills/) and has no .claude-plugin/plugin.json:
- passes
claude plugin validate . --stricton both CLI 2.1.153 and 2.1.259, - installs and loads fine with
claude plugin marketplace add+claude plugin install(CLI 2.1.153 and 2.1.259), - but fails to sync in Claude Desktop → Cowork → Customize → Plugins → Personal → Add from repository.
The Desktop UI only shows the generic "Marketplace sync failed. Check the repository URL and try again." The real reason is only visible in ~/Library/Logs/Claude/claude.ai-web.log:
MARKETPLACE_ERROR:REMOTE_SYNC_FAILED sync did not succeed (status: failed_content):
{"plugins":[{"name":"my-plugin","error":"Plugin 'my-plugin' requires .claude-plugin/plugin.json or a top-level SKILL.md declaring plugin components (set strict: false in marketplace.json to use inline manifest)"}],"message":"1 plugins found, 1 failed validation"}
So there are three related problems:
- CLI ↔ Cowork parity. The plugins reference says "The manifest is optional. If omitted, Claude Code auto-discovers components in default locations and derives the plugin name from the directory name." The CLI honors that. The server-side validator used by Cowork's personal marketplace sync does not: under the default
strict: trueit hard-requiresplugin.json(or a rootSKILL.md). Nothing in the marketplace docs says a marketplace-root / relative-path plugin must ship aplugin.jsonto be distributable through Cowork. claude plugin validate --strictgives a false green. It never warns that the entry has noplugin.json, even though that is fatal for Cowork distribution. Authors validate locally, push, and only find out in Cowork.- The Desktop UI hides the actual error. The generic "check the repository URL" wording sends people down the wrong path (private repo / auth). That is exactly what happened here: we spent time on #28125 / #61271 style auth theories, while the log shows the private repo was fetched and read (
1 plugins found) and the failure was manifest validation. Several comments on #28125 and #45130 report the same generic message and may well be this bug rather than an auth problem.
Our marketplace is a private GitHub repo added by owner/repo shorthand, on an individual Max plan. Note: contrary to the assumption in #61271, the sync did read the private repo in our case (the plugin entry was enumerated from marketplace.json).
What Should Happen?
Any one of these would have avoided the problem; ideally all three:
- Parity: the remote validator should apply the same auto-discovery rules as the CLI. If the plugin directory has a
skills/(oragents/,commands/,hooks/) directory, or the marketplace entry itself listsskills, treat the plugin as valid withoutplugin.json, exactly asclaude plugin installdoes. If the stricter rule is intentional for Cowork, document it on the marketplace page. - Validator:
claude plugin validateshould emit a warning for every local-path / marketplace-root entry that has no.claude-plugin/plugin.json, e.g. "plugins[0]: no plugin.json found; Cowork/remote marketplace sync requires one under strict: true (or set strict: false and declare components inline)". With--strictthat becomes an error, which is what CI users want. - Desktop UI: surface the per-plugin error string from
REMOTE_SYNC_FAILED(it is already in the payload) instead of the generic "check the repository URL" message. #61271 asked for this too but was closed as a duplicate of #28125, so the request got lost.
Error Messages/Logs
# Desktop UI (Customize > Plugins > Personal > Add from repository > owner/repo)
Marketplace sync failed. Check the repository URL and try again.
# ~/Library/Logs/Claude/claude.ai-web.log
2026-09-03 19:04:17 [warn] [REACT_QUERY_CLIENT] QueryClient error: {"name":"Error","message":"MARKETPLACE_ERROR:REMOTE_SYNC_FAILED sync did not succeed (status: failed_content): {\"plugins\": [{\"name\": \"my-plugin\", \"error\": \"Plugin 'my-plugin' requires .claude-plugin/plugin.json or a top-level SKILL.md declaring plugin components (set strict: false in marketplace.json to use inline manifest)\"}], \"message\": \"1 plugins found, 1 failed validation\"}" ...}
# ~/Library/Logs/Claude/main.log (same minute)
[NativeMarketplaceReader] Listing marketplaces (native)
[NativeMarketplaceReader] Found 0 marketplace(s)
Steps to Reproduce
Minimal repo (two files):
.claude-plugin/marketplace.json
{
"name": "repro-marketplace",
"owner": { "name": "Example Org" },
"description": "Minimal reproduction marketplace",
"plugins": [
{
"name": "my-plugin",
"source": "./",
"description": "Plugin whose source is the marketplace root; skills auto-discovered from ./skills",
"skills": ["./skills"]
}
]
}
skills/hello/SKILL.md
---
name: hello
description: Says hello. Trigger with /hello.
---
Say hello to the user.
claude plugin validate . --strict→✔ Validation passed(2.1.153 and 2.1.259).claude plugin marketplace add <path-or-owner/repo>thenclaude plugin install my-plugin@repro-marketplace→✔ Successfully installed plugin: my-plugin@repro-marketplace (scope: user); the skill is present in the plugin cache. (Tested with a cleanCLAUDE_CONFIG_DIRon both versions.)- Push the same two files to a GitHub repo. In Claude Desktop: Cowork → Customize → Plugins → Personal → Add marketplace → Add from a repository →
owner/repo→ Sync. - UI: "Marketplace sync failed. Check the repository URL and try again." Log: the
REMOTE_SYNC_FAILED … requires .claude-plugin/plugin.jsonpayload above.
Workaround (confirmed): add .claude-plugin/plugin.json with at least {"name": "my-plugin"} (the name must match the marketplace entry). After that the same repo syncs in Cowork. Setting "strict": false on the entry, since it already declares skills, should also work per the error text, but I did not test that path.
Claude Model
Not applicable (marketplace sync, no model involved)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
CLI 2.1.153 installed; validator and install path also re-tested with 2.1.259 via npx @anthropic-ai/claude-code@latest. Claude Desktop 1.44121.2.
Platform
Anthropic API / claude.ai (individual Max plan)
Operating System
macOS 27.0 (build 26A5416b)
Terminal/Shell
zsh (CLI checks); Claude Desktop app (Cowork checks)
Additional Information
- Marketplace source: private GitHub repository, added by
owner/reposhorthand in the Cowork Personal tab. - The same repository, added in the Code tab of Claude Desktop or via the CLI, works, because that path runs the local CLI (manifest optional, auto-discovery).
- Related: #28125 (Cowork can't add private marketplace), #61271 (generic error hides the server-side reason), #45130 (generic "validation errors" message), #66184 (Personal tab marketplace parity).
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗