11 KiB
Troubleshooting Skills Auto-Activation
Common issues and solutions for skills auto-activation system.
Problem: Hook Not Running At All
Symptoms
- No skill activation messages appear
- Prompts process normally without injected context
Diagnosis
Step 1: Check hook configuration
cat ~/.claude/hooks.json
Should contain:
{
"hooks": [
{
"event": "UserPromptSubmit",
"command": "~/.claude/hooks/user-prompt-submit/skill-activator.js"
}
]
}
Step 2: Test hook manually
echo '{"text": "test backend endpoint"}' | \
node ~/.claude/hooks/user-prompt-submit/skill-activator.js
Should output JSON with decision and possibly additionalContext.
Step 3: Check file permissions
ls -l ~/.claude/hooks/user-prompt-submit/skill-activator.js
Should be executable (-rwxr-xr-x). If not:
chmod +x ~/.claude/hooks/user-prompt-submit/skill-activator.js
Step 4: Check Claude Code logs
tail -f ~/.claude/logs/hooks.log
Look for errors related to skill-activator.
Solutions
Solution 1: Reinstall hook
mkdir -p ~/.claude/hooks/user-prompt-submit
cp skill-activator.js ~/.claude/hooks/user-prompt-submit/
chmod +x ~/.claude/hooks/user-prompt-submit/skill-activator.js
Solution 2: Verify Node.js
which node
node --version
Ensure Node.js is installed and in PATH.
Solution 3: Check hook timeout
{
"hooks": [
{
"event": "UserPromptSubmit",
"command": "~/.claude/hooks/user-prompt-submit/skill-activator.js",
"timeout": 2000 // Increase if needed
}
]
}
Problem: No Skills Activating
Symptoms
- Hook runs successfully
- No skills appear in activation messages
- Debug shows "No skills activated"
Diagnosis
Enable debug mode:
DEBUG=true echo '{"text": "your test prompt"}' | \
node ~/.claude/hooks/user-prompt-submit/skill-activator.js 2>&1
Check for:
- "No rules loaded" → skill-rules.json not found
- "No skills activated" → Keywords/patterns don't match
Solutions
Solution 1: Verify skill-rules.json location
cat ~/.claude/skill-rules.json
If not found:
cp skill-rules.json ~/.claude/skill-rules.json
Solution 2: Test with known keyword
echo '{"text": "create backend controller"}' | \
SKILL_RULES=~/.claude/skill-rules.json \
DEBUG=true \
node ~/.claude/hooks/user-prompt-submit/skill-activator.js 2>&1
Should match "backend-dev-guidelines" if configured.
Solution 3: Check JSON syntax
cat ~/.claude/skill-rules.json | jq '.'
If errors, fix JSON syntax.
Solution 4: Simplify rules for testing
{
"test-skill": {
"type": "test",
"priority": "high",
"promptTriggers": {
"keywords": ["test"]
}
}
}
Test with:
echo '{"text": "test"}' | node ~/.claude/hooks/user-prompt-submit/skill-activator.js
Problem: Wrong Skills Activating
Symptoms
- Skills activate on irrelevant prompts
- Too many false positives
Diagnosis
Enable debug to see why skills matched:
DEBUG=true echo '{"text": "your prompt"}' | \
node ~/.claude/hooks/user-prompt-submit/skill-activator.js 2>&1
Look for "Matched: keyword" or "Matched: intent pattern" to see why.
Solutions
Solution 1: Tighten keywords
Before:
{
"keywords": ["api", "test", "code"]
}
After (more specific):
{
"keywords": ["API endpoint", "integration test", "refactor code"]
}
Solution 2: Use negative patterns
{
"intentPatterns": [
"(?!.*test).*backend" // Match "backend" but not if "test" in prompt
]
}
Solution 3: Increase priority thresholds
{
"test-skill": {
"priority": "low" // Will be deprioritized if others match
}
}
Solution 4: Reduce maxSkills
In skill-activator.js:
const CONFIG = {
maxSkills: 2, // Reduce from 3
};
Problem: Hook Is Slow
Symptoms
- Noticeable delay before Claude responds
- Hook takes >1 second
Diagnosis
Measure hook performance:
time echo '{"text": "test"}' | node ~/.claude/hooks/user-prompt-submit/skill-activator.js
Should be <500ms. If slower, diagnose:
Check number of rules:
cat ~/.claude/skill-rules.json | jq 'keys | length'
More than 10 rules may slow down.
Check pattern complexity:
cat ~/.claude/skill-rules.json | jq '.[].promptTriggers.intentPatterns'
Complex regex patterns slow matching.
Solutions
Solution 1: Optimize regex patterns
Before (slow):
{
"intentPatterns": [
".*create.*backend.*endpoint.*"
]
}
After (faster):
{
"intentPatterns": [
"(create|build).*(backend|API).*(endpoint|route)"
]
}
Solution 2: Cache compiled patterns
Modify hook to compile patterns once:
const compiledPatterns = new Map();
function getCompiledPattern(pattern) {
if (!compiledPatterns.has(pattern)) {
compiledPatterns.set(pattern, new RegExp(pattern, 'i'));
}
return compiledPatterns.get(pattern);
}
Solution 3: Reduce number of rules
Remove low-priority or rarely-used skills.
Solution 4: Parallelize pattern matching
For advanced users, use worker threads to match patterns in parallel.
Problem: Skills Still Don't Activate in Claude
Symptoms
- Hook injects activation message
- Claude still doesn't use the skills
Diagnosis
This means the hook is working, but Claude is ignoring the suggestion.
Check:
- Are skills actually installed?
- Does Claude have access to read skills?
- Are skill descriptions clear?
Solutions
Solution 1: Make activation message stronger
In skill-activator.js, change:
'Before responding, check if any of these skills should be used.'
To:
'⚠️ IMPORTANT: You MUST check these skills before responding. Use the Skill tool to load them.'
Solution 2: Block until skills loaded
Change hook to blocking mode (use cautiously):
{
"hooks": [
{
"event": "UserPromptSubmit",
"command": "~/.claude/hooks/user-prompt-submit/skill-activator.js",
"blocking": true // ⚠️ Experimental
}
]
}
Solution 3: Improve skill descriptions
Ensure skill descriptions are specific:
name: backend-dev-guidelines
description: Use when creating API routes, controllers, services, or repositories - enforces TypeScript patterns, Prisma repository pattern, and Sentry error handling
Solution 4: Reference skills in CLAUDE.md
Add to project's CLAUDE.md:
## Available Skills
- backend-dev-guidelines: Use for all backend code
- frontend-dev-guidelines: Use for all frontend code
- hyperpowers:test-driven-development: Use when writing tests
Problem: Hook Crashes Claude Code
Symptoms
- Claude Code freezes or crashes after hook execution
- Error in hooks.log
Diagnosis
Check error logs:
tail -50 ~/.claude/logs/hooks.log
Look for errors related to skill-activator.
Common causes:
- Infinite loop in hook
- Memory leak
- Unhandled promise rejection
- Blocking operation
Solutions
Solution 1: Add error handling
async function main() {
try {
// ... hook logic
} catch (error) {
console.error('Hook error:', error.message);
// Always return approve on error
console.log(JSON.stringify({ decision: 'approve' }));
}
}
Solution 2: Add timeout protection
const timeout = setTimeout(() => {
console.log(JSON.stringify({ decision: 'approve' }));
process.exit(0);
}, 900); // Exit before hook timeout
// Clear timeout if completed normally
clearTimeout(timeout);
Solution 3: Test hook in isolation
# Run hook with various inputs
for prompt in "test" "backend" "frontend" "debug"; do
echo "Testing: $prompt"
echo "{\"text\": \"$prompt\"}" | \
timeout 2s node ~/.claude/hooks/user-prompt-submit/skill-activator.js
done
Solution 4: Simplify hook
Remove complex logic and test minimal version:
// Minimal hook for testing
console.log(JSON.stringify({
decision: 'approve',
additionalContext: '🎯 Test message'
}));
Problem: Context Overload
Symptoms
- Too many skill activation messages
- Context window fills quickly
- Claude seems overwhelmed
Solutions
Solution 1: Limit activated skills
const CONFIG = {
maxSkills: 1, // Only top match
};
Solution 2: Use priorities strictly
{
"critical-skill": {
"priority": "high" // Only high priority
},
"optional-skill": {
"priority": "low" // Remove low priority
}
}
Solution 3: Shorten activation message
function generateContext(skills) {
return `🎯 Use: ${skills.map(s => s.skill).join(', ')}`;
}
Problem: Inconsistent Activation
Symptoms
- Sometimes activates, sometimes doesn't
- Same prompt gives different results
Diagnosis
This is expected due to:
- Prompt variations (punctuation, wording)
- Context differences (files being edited)
- Keyword order
Solutions
Solution 1: Add keyword variations
{
"keywords": [
"backend",
"back end",
"back-end",
"server side",
"server-side"
]
}
Solution 2: Use more patterns
{
"intentPatterns": [
"create.*backend",
"backend.*create",
"build.*API",
"API.*build"
]
}
Solution 3: Log all prompts for analysis
// Add to hook
fs.appendFileSync(
path.join(process.env.HOME, '.claude/prompt-log.txt'),
`${new Date().toISOString()} | ${prompt.text}\n`
);
Analyze monthly:
grep "backend" ~/.claude/prompt-log.txt | wc -l
General Debugging Tips
Enable full debug logging:
# Add to hook
const logFile = path.join(process.env.HOME, '.claude/hook-debug.log');
function debug(msg) {
fs.appendFileSync(logFile, `${new Date().toISOString()} ${msg}\n`);
}
debug(`Analyzing prompt: ${prompt.text}`);
debug(`Activated skills: ${activatedSkills.map(s => s.skill).join(', ')}`);
Test with controlled inputs:
# Create test suite
cat > test-prompts.json <<EOF
[
{"text": "create backend endpoint", "expected": ["backend-dev-guidelines"]},
{"text": "build react component", "expected": ["frontend-dev-guidelines"]},
{"text": "write test for API", "expected": ["test-driven-development"]}
]
EOF
# Run tests
node test-hook.js
Monitor in production:
# Daily summary
grep "Activated skills" ~/.claude/hook-debug.log | \
grep "$(date +%Y-%m-%d)" | \
sort | uniq -c
Getting Help
If problems persist:
- Check GitHub issues for similar problems
- Share debug output (sanitize sensitive info)
- Test with minimal configuration
- Verify with official examples
Checklist before asking for help:
- Hook runs manually without errors
- skill-rules.json is valid JSON
- Node.js version is current (v18+)
- Debug mode shows expected behavior
- Tested with simplified configuration
- Checked Claude Code logs