375 lines
8.8 KiB
Markdown
375 lines
8.8 KiB
Markdown
# Troubleshooting Plugin Development
|
|
|
|
## Plugin Not Loading
|
|
|
|
### Symptom
|
|
Plugin doesn't appear in `/plugin list` or components aren't available.
|
|
|
|
### Debug Steps
|
|
|
|
1. **Check plugin.json syntax**
|
|
```bash
|
|
# Validate JSON
|
|
cat .claude-plugin/plugin.json | jq .
|
|
```
|
|
If this errors, you have invalid JSON.
|
|
|
|
2. **Verify directory structure**
|
|
```bash
|
|
# Ensure .claude-plugin/ exists at plugin root
|
|
ls -la .claude-plugin/
|
|
# Should show plugin.json (required)
|
|
```
|
|
|
|
3. **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 `./`
|
|
|
|
4. **Restart Claude Code**
|
|
- Changes only take effect after restart
|
|
- Exit and relaunch the application
|
|
|
|
5. **Check installation**
|
|
```bash
|
|
/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
|
|
|
|
1. **Check YAML frontmatter format**
|
|
```markdown
|
|
---
|
|
name: skill-name
|
|
description: Use when [clear trigger] - [what it does]
|
|
---
|
|
```
|
|
- Must have `---` delimiters
|
|
- Must include `name` and `description`
|
|
- No tabs, only spaces for indentation
|
|
|
|
2. **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`
|
|
|
|
3. **Test explicitly**
|
|
Ask for a task that exactly matches the description:
|
|
```
|
|
"I need to debug a test failure"
|
|
# Should trigger systematic-debugging skill
|
|
```
|
|
|
|
4. **Check skill location**
|
|
- Must be in `skills/skill-name/SKILL.md`
|
|
- NOT in `.claude-plugin/skills/`
|
|
|
|
### 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
|
|
|
|
1. **Verify location**
|
|
```bash
|
|
ls -la commands/
|
|
# Should show command-name.md files
|
|
```
|
|
Commands must be at `commands/` in plugin root, NOT in `.claude-plugin/`
|
|
|
|
2. **Check markdown format**
|
|
```markdown
|
|
---
|
|
description: Brief description of what this command does
|
|
---
|
|
|
|
# Command Instructions
|
|
|
|
Content here...
|
|
```
|
|
|
|
3. **Restart Claude Code**
|
|
Commands are loaded at startup.
|
|
|
|
4. **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
|
|
|
|
1. **Verify path variables**
|
|
All paths in MCP config must use `${CLAUDE_PLUGIN_ROOT}`:
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"my-server": {
|
|
"command": "node",
|
|
"args": ["${CLAUDE_PLUGIN_ROOT}/server/index.js"]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
2. **Check executable permissions**
|
|
```bash
|
|
chmod +x server/index.js
|
|
# Or for shell scripts:
|
|
chmod +x bin/server.sh
|
|
```
|
|
|
|
3. **Test server independently**
|
|
```bash
|
|
# Run server outside Claude Code to check for errors
|
|
node ${PLUGIN_ROOT}/server/index.js
|
|
```
|
|
|
|
4. **Check logs**
|
|
```bash
|
|
claude --debug
|
|
# Look for MCP server startup errors
|
|
```
|
|
|
|
5. **Verify command exists**
|
|
```bash
|
|
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
|
|
|
|
1. **Check hooks.json location**
|
|
Must be at `hooks/hooks.json` in plugin root.
|
|
|
|
2. **Verify JSON format**
|
|
```bash
|
|
cat hooks/hooks.json | jq .
|
|
```
|
|
|
|
3. **Check matcher syntax**
|
|
```json
|
|
{
|
|
"hooks": {
|
|
"PostToolUse": [
|
|
{
|
|
"matcher": "Write|Edit", // Regex - matches Write OR Edit
|
|
"hooks": [...]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
4. **Verify script paths**
|
|
```json
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh"
|
|
}
|
|
```
|
|
|
|
5. **Check script permissions**
|
|
```bash
|
|
chmod +x scripts/format.sh
|
|
```
|
|
|
|
6. **Test script directly**
|
|
```bash
|
|
# 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:**
|
|
1. Check marketplace.json exists in `.claude-plugin/`
|
|
2. Verify marketplace is added:
|
|
```bash
|
|
/plugin marketplace add /full/path/to/plugin
|
|
/plugin marketplace list # Should show your marketplace
|
|
```
|
|
3. Check marketplace.json format:
|
|
```json
|
|
{
|
|
"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:**
|
|
1. Uninstall → modify → reinstall → restart:
|
|
```bash
|
|
/plugin uninstall my-plugin@my-dev
|
|
# Make your changes
|
|
/plugin install my-plugin@my-dev
|
|
# Restart Claude Code
|
|
```
|
|
2. For hook/MCP changes, restart is mandatory
|
|
3. 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:
|
|
|
|
1. **Validate all JSON files**
|
|
```bash
|
|
jq . .claude-plugin/plugin.json
|
|
jq . .claude-plugin/marketplace.json
|
|
jq . hooks/hooks.json
|
|
```
|
|
|
|
2. **Check all paths use variables**
|
|
```bash
|
|
grep -r "Users/" .
|
|
# Should return nothing in config files
|
|
```
|
|
|
|
3. **Verify permissions**
|
|
```bash
|
|
find . -name "*.sh" -o -name "*.js" | xargs ls -l
|
|
# Check executable bit (x) is set
|
|
```
|
|
|
|
4. **Test components independently**
|
|
- Run MCP servers directly
|
|
- Execute hook scripts manually
|
|
- Validate YAML frontmatter with a parser
|
|
|
|
5. **Clean reinstall**
|
|
```bash
|
|
/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
|
|
```
|
|
|
|
6. **Check logs**
|
|
```bash
|
|
claude --debug
|
|
# Look for error messages during startup
|
|
```
|
|
|
|
---
|
|
|
|
## Getting Help
|
|
|
|
If you're still stuck:
|
|
|
|
1. **Read official docs** via `working-with-claude-code` skill
|
|
2. **Check example plugins** in this repo and `~/.claude/plugins/`
|
|
3. **Simplify** - Remove components until it works, then add back one at a time
|
|
4. **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
|