Files
2025-11-30 09:06:38 +08:00

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:

  1. Are skills actually installed?
  2. Does Claude have access to read skills?
  3. 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:

  1. Check GitHub issues for similar problems
  2. Share debug output (sanitize sensitive info)
  3. Test with minimal configuration
  4. 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