Automated error detection, fix tracking, and prevention for Claude Code. Learns from mistakes and teaches future sessions the fixes.
ERROR OCCURS FIX APPLIED FUTURE SESSIONS
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Capture │ │ Capture │ │ Prevent │
│ Error │────────────────▶│ Fix │─────────────────▶ │ + Teach │
│ │ same session │ │ curator pairs │ │
└──────────┘ same tool type └──────────┘ error → fix └──────────┘
│ │ │
▼ ▼ ▼
errors.jsonl errors.jsonl learned.json
{cmd, error} {fix, linked_to} {block, learned_fix}
Result: Claude makes mistake once → learns the fix → never makes that mistake again.
The plugin analyzes error messages, not just command patterns, to create precise blocking rules:
| Error Type | What Gets Blocked | Example |
|---|---|---|
Bad flag --xyz |
Only that specific flag | ls --invalid blocked, ls -la works |
| Command not found | Only that command | choco blocked, other commands work |
| Path not found | Nothing (environmental) | Won't learn from missing files |
| Permission denied | Nothing (environmental) | Won't learn from access errors |
This prevents false positives like blocking all ls commands just because one bad flag failed.
# macOS/Linux
git clone https://github.com/jonathondouglasyager-debug/claude-error-learning.git ~/claude-error-learning
# Windows
git clone https://github.com/jonathondouglasyager-debug/claude-error-learning.git %USERPROFILE%\claude-error-learningAdd the following to your ~/.claude/settings.json (macOS/Linux) or %USERPROFILE%\.claude\settings.json (Windows):
macOS/Linux:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 \"$HOME/claude-error-learning/hooks/command-validator.py\""
}
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 \"$HOME/claude-error-learning/hooks/fix-tracker.py\""
}
]
}
],
"PostToolUseFailure": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 \"$HOME/claude-error-learning/hooks/error-logger.py\""
}
]
}
],
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "python3 \"$HOME/claude-error-learning/hooks/error-curator.py\" --auto"
}
]
}
]
}
}Windows:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python \"%USERPROFILE%\\claude-error-learning\\hooks\\command-validator.py\""
}
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python \"%USERPROFILE%\\claude-error-learning\\hooks\\fix-tracker.py\""
}
]
}
],
"PostToolUseFailure": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python \"%USERPROFILE%\\claude-error-learning\\hooks\\error-logger.py\""
}
]
}
],
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "python \"%USERPROFILE%\\claude-error-learning\\hooks\\error-curator.py\" --auto"
}
]
}
]
}
}cd ~/claude-error-learning # or %USERPROFILE%\claude-error-learning on Windows
# macOS/Linux users:
python3 hooks/error-curator.py --enable linux
# Windows users:
python hooks/error-curator.py --enable windowsStart a new Claude session for hooks to take effect.
After installation, the plugin works automatically:
- Errors are captured when any tool fails
- Fixes are tracked when a successful command follows a failed one
- Patterns are learned at session end (if seen 2+ times)
- Commands are blocked in future sessions with the learned fix shown
Use the slash command to manage:
/error-learning # Show status and stats
/error-learning review # Review pending patterns
/error-learning packs # List available pattern packs
Patterns are organized into packs that can be enabled/disabled:
| Pack | Description | Default |
|---|---|---|
common |
Universal patterns (use Read not cat, etc.) | Enabled |
windows |
Windows/PowerShell patterns | Disabled |
linux |
Linux/bash patterns | Disabled |
learned |
Auto-learned from your errors | Enabled |
custom |
Your manual additions | Enabled |
Interactive (no coding):
- Double-click
manage-packs.pyor use Desktop shortcut - Type a number to toggle packs on/off
CLI:
python hooks/error-curator.py --packs # List all packs
python hooks/error-curator.py --enable windows # Enable a pack
python hooks/error-curator.py --disable linux # Disable a packIf a command gets incorrectly blocked, add it to the allowlist to bypass all learned patterns:
# List current allowlist
python hooks/error-curator.py --allowlist
# Allow by prefix (matches "ls -la", "ls foo", etc.)
python hooks/error-curator.py --allow "ls "
# Allow exact command only
python hooks/error-curator.py --allow-exact "git status"
# Allow by regex pattern
python hooks/error-curator.py --allow-regex "^npm (run|test|install)"
# Remove from allowlist
python hooks/error-curator.py --unallow "ls "The allowlist is checked before blocking patterns, so it acts as an override.
Slash command:
/error-learning packs # List all packs
/error-learning packs enable windows # Enable Windows patterns
/error-learning packs disable linux # Disable Linux patterns
Or edit config.json directly:
{
"enabled_packs": ["common", "windows", "learned", "custom"],
"auto_curate": true,
"curate_threshold": 2,
"show_confidence": true
}| Hook | File | Purpose |
|---|---|---|
| PostToolUseFailure | error-logger.py |
Captures errors with awaiting_fix flag |
| PostToolUse (Bash) | fix-tracker.py |
Links successful commands to prior errors |
| PreToolUse (Bash) | command-validator.py |
Blocks known-bad commands, shows fix |
| SessionEnd | error-curator.py |
Pairs errors with fixes, updates patterns |
When an error occurs:
error-logger.pylogs it withawaiting_fix: true- When a successful command follows (same session, same tool)
fix-tracker.pylogs it as a fix linked to the error- At session end,
error-curator.pypairs them and extracts patterns
When a blocked command is detected:
BLOCKED: '&&' doesn't work here.
LEARNED FIX (87% confidence): Use "cmd1; cmd2" instead
The confidence score is based on how often the fix worked.
error-learning/
├── plugin.json # Plugin manifest
├── config.json # User settings
├── manage-packs.py # Interactive pack manager (double-click!)
├── hooks/
│ ├── error-logger.py # PostToolUseFailure
│ ├── fix-tracker.py # PostToolUse (Bash)
│ ├── command-validator.py # PreToolUse (Bash)
│ └── error-curator.py # SessionEnd + CLI commands
├── patterns/
│ ├── active.json # Merged patterns (auto-generated)
│ ├── allowlist.json # Commands that bypass blocking
│ └── packs/
│ ├── common.json # Universal patterns
│ ├── windows.json # Windows/PowerShell
│ ├── linux.json # Linux/bash
│ ├── learned.json # Auto-learned
│ └── custom.json # User additions
├── commands/
│ └── error-learning.md # Slash command
└── data/ # gitignored
├── errors.jsonl # Error + fix log
└── curator.log # Curation activity
python hooks/error-curator.py --reviewShows all error signatures, their occurrence count, and sample commands.
python hooks/error-curator.py --add-allAdds all detected patterns to learned.json.
python hooks/error-curator.py --add bash_and_chainingpython hooks/error-curator.py --mergeRegenerates active.json from enabled packs.
Use the slash command:
/error-learning add "rm command should use Remove-Item"
Or edit patterns/packs/custom.json:
{
"id": "my_custom_pattern",
"name": "My Custom Pattern",
"category": "custom",
"tool": "Bash",
"match": {
"type": "contains",
"pattern": "bad command"
},
"message": "BLOCKED: Explanation",
"learned_fix": "Use this instead",
"confidence": 100,
"source": "manual"
}Match types: contains, regex, exact
| Scenario | Tokens |
|---|---|
| Without prevention | ~210-610 per error |
| With prevention | ~60 per error |
| Savings | 70-90% |
- Fork this repo
- Add patterns to the appropriate pack
- Submit a PR
Pattern contributions welcome for:
- Platform-specific gotchas
- Common tool misuse patterns
- Language-specific errors
MIT