8.8 KiB
Troubleshooting Plugin Development
Plugin Not Loading
Symptom
Plugin doesn't appear in /plugin list or components aren't available.
Debug Steps
-
Check plugin.json syntax
# Validate JSON cat .claude-plugin/plugin.json | jq .If this errors, you have invalid JSON.
-
Verify directory structure
# Ensure .claude-plugin/ exists at plugin root ls -la .claude-plugin/ # Should show plugin.json (required) -
Check all paths
- Search for hardcoded paths:
grep -r "/Users/" .claude-plugin/ - Should use
${CLAUDE_PLUGIN_ROOT}instead - Relative paths in plugin.json must start with
./
- Search for hardcoded paths:
-
Restart Claude Code
- Changes only take effect after restart
- Exit and relaunch the application
-
Check installation
/plugin list # Your plugin should appear here
Common Causes
| Problem | Solution |
|---|---|
.claude-plugin/ missing |
Create directory with plugin.json |
Invalid JSON in plugin.json |
Validate with jq or JSON linter |
| Hardcoded paths | Replace with ${CLAUDE_PLUGIN_ROOT} |
| Forgot to restart | Always restart after install/changes |
Skill Not Triggering
Symptom
Skill exists but Claude doesn't use it when expected.
Debug Steps
-
Check YAML frontmatter format
--- name: skill-name description: Use when [clear trigger] - [what it does] ---- Must have
---delimiters - Must include
nameanddescription - No tabs, only spaces for indentation
- Must have
-
Verify description clarity
- Description should clearly state WHEN to use skill
- Use "Use when..." format
- Be specific about triggering conditions
❌ Bad:
description: A helpful skill✅ Good:
description: Use when debugging test failures - systematic approach to finding root causes -
Test explicitly Ask for a task that exactly matches the description:
"I need to debug a test failure" # Should trigger systematic-debugging skill -
Check skill location
- Must be in
skills/skill-name/SKILL.md - NOT in
.claude-plugin/skills/
- Must be in
Common Causes
| Problem | Solution |
|---|---|
| Vague description | Make description specific and action-oriented |
| Skill in wrong location | Move to skills/ at plugin root |
| Missing frontmatter | Add YAML with name and description |
| Malformed YAML | Check for tabs, missing dashes, etc. |
Command Not Appearing
Symptom
Custom slash command doesn't show up or can't be executed.
Debug Steps
-
Verify location
ls -la commands/ # Should show command-name.md filesCommands must be at
commands/in plugin root, NOT in.claude-plugin/ -
Check markdown format
--- description: Brief description of what this command does --- # Command Instructions Content here... -
Restart Claude Code Commands are loaded at startup.
-
Test directly
/your-command-name
Common Causes
| Problem | Solution |
|---|---|
Commands in .claude-plugin/ |
Move to commands/ at root |
| Missing description frontmatter | Add YAML with description |
| No restart after adding | Restart Claude Code |
| Wrong file extension | Must be .md not .txt |
MCP Server Not Starting
Symptom
MCP server tools not available, or server fails silently.
Debug Steps
-
Verify path variables All paths in MCP config must use
${CLAUDE_PLUGIN_ROOT}:{ "mcpServers": { "my-server": { "command": "node", "args": ["${CLAUDE_PLUGIN_ROOT}/server/index.js"] } } } -
Check executable permissions
chmod +x server/index.js # Or for shell scripts: chmod +x bin/server.sh -
Test server independently
# Run server outside Claude Code to check for errors node ${PLUGIN_ROOT}/server/index.js -
Check logs
claude --debug # Look for MCP server startup errors -
Verify command exists
which node # Or whatever command you're using
Common Causes
| Problem | Solution |
|---|---|
| Hardcoded paths | Use ${CLAUDE_PLUGIN_ROOT} |
| Not executable | chmod +x on scripts |
| Command not in PATH | Use full path or ensure command available |
| Server crashes on startup | Test independently, check logs |
| Missing dependencies | npm install or equivalent |
Hooks Not Firing
Symptom
Hook scripts exist but don't execute when events occur.
Debug Steps
-
Check hooks.json location Must be at
hooks/hooks.jsonin plugin root. -
Verify JSON format
cat hooks/hooks.json | jq . -
Check matcher syntax
{ "hooks": { "PostToolUse": [ { "matcher": "Write|Edit", // Regex - matches Write OR Edit "hooks": [...] } ] } } -
Verify script paths
{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh" } -
Check script permissions
chmod +x scripts/format.sh -
Test script directly
# Run the hook script manually ./scripts/format.sh
Common Causes
| Problem | Solution |
|---|---|
| Wrong hooks.json location | Move to hooks/ at plugin root |
| Script not executable | chmod +x on all scripts |
| Invalid matcher regex | Test regex syntax |
| Script fails silently | Add error handling, test independently |
| Hardcoded paths | Use ${CLAUDE_PLUGIN_ROOT} |
Development Workflow Issues
Can't Install Plugin Locally
Problem: /plugin install my-plugin@my-dev fails
Solutions:
- Check marketplace.json exists in
.claude-plugin/ - Verify marketplace is added:
/plugin marketplace add /full/path/to/plugin /plugin marketplace list # Should show your marketplace - Check marketplace.json format:
{ "name": "my-dev", "plugins": [{ "name": "my-plugin", "source": "./" // Points to plugin root }] }
Changes Not Taking Effect
Problem: Modified plugin but changes don't appear
Solutions:
- Uninstall → modify → reinstall → restart:
/plugin uninstall my-plugin@my-dev # Make your changes /plugin install my-plugin@my-dev # Restart Claude Code - For hook/MCP changes, restart is mandatory
- For skill/command content changes, sometimes works without restart (but safer to restart)
Common Pitfalls Summary
| Mistake | Why It Fails | How to Fix |
|---|---|---|
Skills in .claude-plugin/skills/ |
Claude looks in skills/ at root |
Move to plugin root |
| Hardcoded absolute paths | Breaks on other systems | Use ${CLAUDE_PLUGIN_ROOT} |
| Forgot to restart | Changes load at startup | Always restart after changes |
| Script not executable | Shell can't run it | chmod +x script.sh |
| Invalid JSON | Parser fails silently | Validate with jq or linter |
| Vague skill description | Claude doesn't know when to use it | Be specific about triggers |
| Missing YAML frontmatter | Metadata not parsed | Add --- delimiters and fields |
| Testing without uninstall | Old version still cached | Uninstall before reinstalling |
Debugging Workflow
When something isn't working:
-
Validate all JSON files
jq . .claude-plugin/plugin.json jq . .claude-plugin/marketplace.json jq . hooks/hooks.json -
Check all paths use variables
grep -r "Users/" . # Should return nothing in config files -
Verify permissions
find . -name "*.sh" -o -name "*.js" | xargs ls -l # Check executable bit (x) is set -
Test components independently
- Run MCP servers directly
- Execute hook scripts manually
- Validate YAML frontmatter with a parser
-
Clean reinstall
/plugin uninstall my-plugin@my-dev /plugin marketplace remove /path/to/plugin # Fix issues /plugin marketplace add /path/to/plugin /plugin install my-plugin@my-dev # Restart Claude Code -
Check logs
claude --debug # Look for error messages during startup
Getting Help
If you're still stuck:
- Read official docs via
working-with-claude-codeskill - Check example plugins in this repo and
~/.claude/plugins/ - Simplify - Remove components until it works, then add back one at a time
- Report issues at https://github.com/anthropics/claude-code/issues
Pro tip: When asking for help, include:
- Your plugin.json
- Directory structure (
tree -L 3 -a) - Exact error messages
- What you've already tried