[BUG] Account-level plugins never sync to Claude Code on the web (plugins_sync count: 0) while account skills sync fine

Status Open
Reported on v2.1.260
Maintainer reply None cached
Activity 5 comments · opened Sep 4, 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?

Plugins installed at the account level (claude.ai -> Settings -> Customize -> Plugins)
never reach Claude Code on the web / remote cloud sessions.

Account-level SKILLS sync into the same session correctly, so the transport works.
Only the plugin half comes back empty. The sync runs, no gate closes, and the server
returns an empty plugin list.

Net effect: there is no way to enable a plugin for all projects without owning a
computer that runs the Claude Code CLI or desktop app. Phone-only users cannot use
plugins at all, and someone with two computers has to repeat the setup on each.

What Should Happen?

An enabled account-level plugin should be available in Claude Code web/cloud sessions,
the same way account-level skills already are.

Error Messages/Logs

plugins_sync_starting
plugins_sync_no_changes {"count":0,"duration_ms":600,"list_ms":177,"had_manifest":false}
[DEBUG] installed_plugins.json doesn't exist, returning empty V2 object
[DEBUG] Found 0 plugins (0 enabled, 0 disabled)
[DEBUG] Total plugin skills loaded: 0
[DEBUG] Registered 0 hooks from 0 plugins

Same session, same sync pass, skills succeed:
skills_sync_starting
skills_sync_complete {"downloaded":9,"removed":0,"duration_ms":1867}

Repository-settings workaround, on the session's own branch:
installPluginsForHeadless: starting
installPluginsForHeadless: no marketplaces declared

Steps to Reproduce

  1. claude.ai -> Settings -> Customize -> Plugins -> Add -> Add marketplace ->

Add from a repository -> https://github.com/DietrichGebert/ponytail

  1. Install the ponytail plugin. Its page shows 6 skills, 3 hooks, toggle ON.
  2. Open a NEW Claude Code session on the web (claude.ai/code).
  3. Run: ls -la ~/.claude/plugins/synced/*/

-> empty

  1. Run: grep -h '"event":"plugins_sync' /tmp/claude-code-*.diag.log | tail -5

-> plugins_sync_no_changes {"count":0,"had_manifest":false}

  1. Call ListPlugins -> {"results":[]}
  2. Compare: ls ~/.claude/skills/synced/*/ -> all 9 account skills present.

Claude Model

Opus

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

2.1.260

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Other

Additional Information

Workarounds tried, all fail:

  1. Settings -> Claude Code: no plugin toggle exists anywhere on that page.
  2. Plugin page's ... menu: only "Remove". No per-surface option.
  3. Repository .claude/settings.json with extraKnownMarketplaces + enabledPlugins,

verified on the session's own branch: "no marketplaces declared", logged in the
same millisecond as "starting". Project settings appear not to be read, which
contradicts the settings docs describing extraKnownMarketplaces as
repository-level.

  1. /cloud-plugins consent: needs a machine running the CLI or desktop app, and the

prompt is scoped to "cloud sessions you run from this machine" - so it does not
cover a second computer, and never covers a phone.

Why this looks like a gap rather than a design choice: the account-level plugin sync
path already exists and mirrors the skills one exactly.

{ settingKey: "syncClaudeAiPlugins",
policyKey: "allow_account_plugins_sync",
flagName: "tengu_account_plugins_sync_enabled" }

Skills use allow_account_skills_sync and work. Same architecture, same
/api/oauth/organizations/:orgUUID/plugins/list-plugins endpoint shape. One half
delivers, the other returns nothing.

No gate ever closed - no flag_off, org_denied, gate_closed or policy_verdict_pending
in the diagnostics log.

Environment: CLAUDE_CODE_ENTRYPOINT=remote,
CLAUDE_CODE_REMOTE_ENVIRONMENT_TYPE=cloud_default, personal account, no org admin
access, no machine has ever run /cloud-plugins.

Request: make account-level plugins sync to web/cloud sessions the way account-level
skills already do. Failing that, document that plugins require a computer, and make
extraKnownMarketplaces in repository settings work for cloud sessions.

View original on GitHub ↗

3 Comments

Swordsman · 1 month ago

Running into the same issue, Claude wrote this as additional info to contribute, hopefully this gets fixed soon, because this bug is seriously obnoxious, and the observed behavior does not match what the docs say:

Root cause: SKIP_PLUGIN_MARKETPLACE=true in the container environment

I hit this same issue and traced it to the source. The cloud_default remote environment injects SKIP_PLUGIN_MARKETPLACE=true into the parent process environment (the claude launcher, PID 1's child). This kills the entire plugin marketplace sync pipeline before it evaluates any plugin config.

Diagnostic evidence

Process environment chain:

$ tr '\0' '\n' < /proc/$PPID/environ | grep -i "SKIP\|PLUGIN\|MARKET\|SYNC_SKILL"
SKIP_PLUGIN_MARKETPLACE=true
ENVRUNNER_SKIP_ACK=true

$ env | grep SYNC_SKILLS
CLAUDE_CODE_SYNC_SKILLS=1

Note: CLAUDE_CODE_SYNC_SKILLS=1 exists and works. There is no CLAUDE_CODE_SYNC_PLUGINS equivalent.

Skills vs plugins - same bucket UUID, different outcomes:

# Skills bucket - populated, 13 skills loaded:
~/.claude/skills/synced/.../ → manifest.json, 13 skill directories

# Plugins bucket - empty skeleton:
~/.claude/plugins/synced/.../ → just . and ..

The bucket marker file (.bucket-...) is created in both directories, indicating the sync infrastructure knows about the plugin bucket; it just never populates it.

ListPlugins returns []; ListSkills returns all 13 skills correctly.

Additional finding: undocumented reach field

Every plugin in the SearchPlugins API has a reach field ("remote" or "contained"), but this field is absent from the plugin.json schema documentation. It's unclear whether this is author-set or computed server-side, and whether it plays a role in the sync decision alongside or independently of SKIP_PLUGIN_MARKETPLACE. These may be layered blockers.

Environment details

  • CLAUDE_CODE_REMOTE_ENVIRONMENT_TYPE=cloud_default
  • CLAUDE_CODE_ENTRYPOINT=remote
  • CLAUDE_CODE_VERSION=2.1.42
  • Plugin configured via claude.ai marketplace settings, shows "synced" at correct commit
  • Repo is public, plugin.json structure validates correctly
  • User env var override (SKIP_PLUGIN_MARKETPLACE=) has no effect; the parent process already consumed the flag before shell-level overrides apply

What the docs say

plugins-reference.md:

"In Cowork and cloud sessions, Claude Code downloads the plugins enabled for your claude.ai account into ~/.claude/plugins/synced/ in the session's own environment and loads each one as <name>@synced."

cloud-environments.md:

"Plugins declared in .claude/settings.json: Yes - Installed at session start from the marketplace you declared."

The documented behavior and the actual behavior directly contradict.

mnmkng · 1 month ago

+1

Reproduced today with a different marketplace and a Team plan account.

Setup

  • Claude Code 2.1.270 in Anthropic-hosted cloud sessions (claude.ai/code), two different cloud environments.
  • Private personal marketplace: https://github.com/mnmkng/Claude (.claude-plugin/marketplace.json, one plugin personal-productivity with one skill todoist).
  • claude plugin validate passes on both manifests. Inside the same cloud container image, claude plugin marketplace add mnmkng/Claude + claude plugin install personal-productivity@mnmkng-personal succeed and claude plugin details lists the skill. So the marketplace itself is fine.
  • Enabled the plugin at account level via Claude Desktop → Chat and Cowork → Customize → Plugins → Add → Add from a repository. It shows under "Your plugins" there.

I tested the /todoist skill's availability in Chat and on mobile and both work, but never in Claude Code cloud.

Result in a fresh cloud session started after enabling

{"event":"plugins_sync_starting","data":{}}
{"event":"plugins_sync_no_changes","data":{"count":0,"duration_ms":908,"list_ms":380,"had_manifest":false}}
{"event":"plugins_sync_wait","data":{"timed_out":false}}

~/.claude/plugins/synced/<bucket>/ contains only the bucket marker. claude plugin list reports no plugins and no "Synced from claude.ai" heading. The skill is absent from the system prompt.
In the same session, account skills sync works: skills_sync_complete {"downloaded":13} on first start, and it re-runs every ~10 minutes. Plugin sync runs only once at session start.

Side note on UX that cost me an hour: the Desktop app's Code tab has its own Customize → Plugins page, but it manages the local ~/.claude store only ("Marketplaces added with Claude Code on this computer"). Plugins enabled there are invisible to cloud sessions by design. The account-level page is under the Chat and Cowork tab. That is not obvious when you are configuring Claude Code and running it in the cloud.

barnent1 · 22 days ago

+1, reproduced 2026-09-22 on a Max plan, Claude Code 2.1.278.

Probe: a minimal plugin (one skill, one subagent, a SessionStart hook that prints a
marker, a PreToolUse hook that denies one sentinel command). claude plugin validate
passes, and it works end to end locally with --plugin-dir.

Uploaded via claude.ai (Chat tab) > Customize > Plugins; it lands in "My Uploads"
with account scope. A terminal session on the same account syncs it
(claude plugin list shows it under "Synced from claude.ai"), along with two
Anthropic plugins.

A fresh cloud session started ~11 min after upload:

  • ~/.claude/plugins/synced/<bucket>/ exists but is empty
  • installed_plugins.json = {"version": 2, "plugins": {}}
  • the sentinel command ran; the PreToolUse hook did not fire
  • no marker from SessionStart; the skill and subagent are absent
  • ~/.claude/skills/synced/<bucket>/ has all account skills, same bucket id

So the local terminal gets all three account plugins, and the cloud session on the
same version gets none. This also blocks plugins in Claude Code Projects, since
every thread is a cloud session.

Showing cached comments. Read the full discussion on GitHub ↗