Claude Code Plugin Bug Causes Skills to Load Twice, Increasing Context Compaction

A bug in Claude Code causes plugins to load every skill twice, significantly increasing system prompt size and triggering frequent context compaction. The issue stems from stale plugin cache directories not being cleaned up during auto-updates and duplicate symlinks in the skills directory.
The Problem
When plugins update (e.g., from version 4.3.0 to 4.3.1), the old version directory remains in ~/.claude/plugins/cache/. Claude Code loads skills from ALL cached versions, not just the active one listed in installed_plugins.json. This causes every skill to appear twice in the system prompt.
One user reported having 11 stale version directories across 6 plugins, which doubled their ~30 skills to ~60 entries. Additional duplication vectors include a bug in prompt construction itself (confirmed in issue #29520) and symlinks created in ~/.claude/skills/ pointing back to the plugin cache (issue #23819), where one reporter had 83 symlinks batch-created.
Check if You're Affected
Run these scripts to check for the issue:
Check 1: Stale plugin versions
for d in ~/.claude/plugins/cache/claude-plugins-official/*/; do
name=$(basename "$d")
count=$(ls -d "$d"*/ 2>/dev/null | wc -l)
if [ "$count" -gt 1 ]; then
echo "AFFECTED: $name has $count versions (should be 1)"
ls -d "$d"*/
fi
done
Check 2: Duplicate symlinks
ls -la ~/.claude/skills/ 2>/dev/null | grep -c "plugins/"
If this returns a number > 0, you have symlink duplicates.
Check 3: From inside a session — run /context and look at the Skills table. If every skill appears twice, you're affected.
Fix the Issue
Fix stale versions:
python3 << 'EOF'
import json, os, shutil
with open(os.path.expanduser("~/.claude/plugins/installed_plugins.json")) as f:
data = json.load(f)
cache = os.path.expanduser("~/.claude/plugins/cache/claude-plugins-official")
for full_name, installs in data["plugins"].items():
plugin = full_name.split("@")[0]
active = installs[0]["version"]
plugin_dir = os.path.join(cache, plugin)
if os.path.isdir(plugin_dir):
for ver in os.listdir(plugin_dir):
path = os.path.join(plugin_dir, ver)
if os.path.isdir(path) and ver != active:
print(f"Removing stale: {plugin}/{ver}")
shutil.rmtree(path)
EOF
Fix duplicate symlinks:
find ~/.claude/skills/ -type l -lname "*plugins/*" -delete 2>/dev/null
Restart Claude Code after running these fixes.
Additional Context Savings
The source also recommends:
- Audit your enabled plugins in
~/.claude/settings.json→enabledPlugins. Disable what you don't need for your current project. - Disconnect unused MCP connectors (Gmail, GCal, etc.).
- Run
/contextin your next session to see the difference. - Thumbs-up issue #27721 so it gets prioritized — it's the root issue with no response yet.
📖 Read the full source: r/ClaudeAI
👀 See Also

Switching from GitHub Copilot Pro+ to Direct Anthropic API: A Cost Analysis
A developer's cost comparison shows direct Anthropic API can be cheaper than GitHub Copilot Pro+ for solo devs, with Sonnet 4.6 covering 80% of Opus use cases.

KV Cache Quantization Issues in Local Coding Agents at High Context Lengths
A Reddit analysis identifies aggressive KV cache quantization as the cause of infinite correction loops and malformed JSON outputs in local coding agents like Qwen3-Coder and GLM 4.7 at 30k+ context lengths, recommending mixed precision or reduced context as workarounds.

Verification Harness Fixes Claude's Plan Execution Problem
A developer built a 30-50 line bash or Python verification layer that checks whether Claude actually executes each step of its own plans by verifying artifacts like file existence, API responses, and config changes.

Compress CLAUDE.md Files to Reduce System Prompt Bloat in Claude Code
A technique for compressing CLAUDE.md files by removing human-readable formatting like markdown headers and prose, replacing them with compact notation like pipe-delimited lists, achieving 60-70% character reduction while maintaining the same information for Claude.