Claude Code Troubleshooting Master MOC

Tags: claude-code troubleshooting debugging error-handling moc

A comprehensive guide consolidating all troubleshooting resources across Claude Code, TypeScript SDK, Hooks, and Subagents.

🚨 Quick Emergency Procedures

System Down

  1. Check Claude Code status: claude doctor
  2. Verify API key: echo $ANTHROPIC_API_KEY
  3. Test connection: claude -p "Hello"
  4. Check logs: tail -f ~/.claude/logs/*

Disable All Hooks

# Temporarily rename settings
mv .claude/settings.json .claude/settings.json.disabled
 
# Or use empty configuration
echo '{"hooks": {}}' > .claude/settings.json

Reset Environment

# Clear cache
rm -rf ~/.claude/cache/*
 
# Reset configuration
claude setup-token
 
# Migrate to local install (fixes permissions)
claude migrate-installer

πŸ“Š Troubleshooting by Component

TypeScript SDK Troubleshooting

Hooks Troubleshooting

Subagents Troubleshooting

πŸ” Common Issues Across All Components

1. Authentication Problems

Symptoms

  • 401 Authentication errors
  • β€œInvalid API key” messages
  • OAuth token expired

Solutions

# Check API key
echo $ANTHROPIC_API_KEY
 
# Regenerate OAuth token
claude setup-token
 
# Validate API key format
[[ "$ANTHROPIC_API_KEY" =~ ^sk-ant- ]] && echo "Valid" || echo "Invalid format"

Debug Script

async function debugAuth() {
  console.log('Checking authentication setup...');
  
  // Check environment
  console.log('- ANTHROPIC_API_KEY set:', !!process.env.ANTHROPIC_API_KEY);
  
  // Check config file
  const configPath = path.join(os.homedir(), '.config/claude/settings.json');
  console.log('- Config file exists:', fs.existsSync(configPath));
  
  // Test connection
  try {
    const test = await query({
      prompt: 'Hello',
      abortController: new AbortController(),
      options: { maxTurns: 1 }
    });
    console.log('βœ… Authentication successful');
  } catch (error) {
    console.error('❌ Authentication failed:', error.message);
  }
}

2. Permission Issues

Symptoms

  • EACCES errors during installation
  • Cannot write to directories
  • Hook scripts not executing

Solutions

# Fix npm permissions
npm config set prefix ~/.npm-global
export PATH=~/.npm-global/bin:$PATH
 
# Migrate Claude to local install
claude migrate-installer
 
# Fix hook permissions
chmod +x .claude/hooks/*.sh

3. Performance Problems

Symptoms

  • Slow response times
  • Timeouts
  • High memory usage

Solutions

// Add timeouts
const abortController = new AbortController();
setTimeout(() => abortController.abort(), 120000); // 2 minutes
 
// Use streaming for large operations
const stream = await client.messages.stream({
  model: 'claude-3-opus-20240229',
  messages: [{ role: 'user', content: prompt }],
  max_tokens: 4096,
  stream: true
});
 
// Process without accumulation
for await (const chunk of stream) {
  process.stdout.write(chunk.delta?.text || '');
}

πŸ› οΈ TypeScript SDK Troubleshooting {#typescript-sdk}

Common SDK Errors

ErrorCodeCauseSolution
AuthenticationError401Invalid API keyCheck ANTHROPIC_API_KEY
RateLimitError429Too many requestsImplement retry with backoff
APIConnectionTimeoutError-Request too longUse streaming or increase timeout
BadRequestError400Invalid parametersValidate input format

Module Import Issues

# Check installation
npm list @anthropic-ai/claude-code
 
# Reinstall if needed
npm cache clean --force
npm install @anthropic-ai/claude-code
 
# For TypeScript projects
npm install --save-dev @types/node

Rate Limit Handler

class RateLimitManager {
  private lastRequestTime = 0;
  private minInterval = 1000; // 1 second between requests
  
  async throttledQuery(params: QueryParams): Promise<SDKMessage[]> {
    const now = Date.now();
    const timeSinceLastRequest = now - this.lastRequestTime;
    
    if (timeSinceLastRequest < this.minInterval) {
      await this.sleep(this.minInterval - timeSinceLastRequest);
    }
    
    this.lastRequestTime = Date.now();
    
    try {
      const messages = [];
      for await (const message of query(params)) {
        messages.push(message);
      }
      return messages;
      
    } catch (error) {
      if (error instanceof Anthropic.RateLimitError) {
        const retryAfter = parseInt(error.headers['retry-after'] || '60');
        console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
        await this.sleep(retryAfter * 1000);
        return this.throttledQuery(params);
      }
      throw error;
    }
  }
  
  private sleep(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

πŸͺ Hooks Troubleshooting {#hooks}

Hook Not Triggering

Diagnosis Checklist

  • Check hooks are loaded: /hooks in Claude Code
  • Validate JSON syntax: jq . .claude/settings.json
  • Test matcher pattern: echo "Edit" | grep -E "Edit|Write"
  • Verify event name (case-sensitive)
  • Check file location (.claude/settings.json)

Test Hook

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Hook test successful' >> /tmp/claude-hook-test.txt"
          }
        ]
      }
    ]
  }
}

Exit Code Reference

Exit CodeEffectUse Case
0Continue normallySuccess
1Warning (continue)Non-critical error
2Block operationValidation failure (PreToolUse only)
OtherWarning (continue)Custom codes

Debug Environment Script

#!/bin/bash
# debug_env.sh
{
    echo "=== Environment Debug ==="
    echo "PATH: $PATH"
    echo "PWD: $PWD"
    echo "USER: $USER"
    echo "SHELL: $SHELL"
    echo ""
    echo "=== Claude Variables ==="
    env | grep CLAUDE
    echo ""
    echo "=== Available Commands ==="
    for cmd in jq git npm python3 node curl; do
        if command -v $cmd &> /dev/null; then
            echo "βœ“ $cmd: $(command -v $cmd)"
        else
            echo "βœ— $cmd: NOT FOUND"
        fi
    done
} >> ~/.claude/env-debug.log

Hook Performance Profiling

#!/bin/bash
# Performance profiling wrapper
 
SCRIPT_TO_PROFILE="$1"
START=$(date +%s.%N)
 
# Run the actual hook
$SCRIPT_TO_PROFILE
 
RESULT=$?
END=$(date +%s.%N)
DURATION=$(echo "$END - $START" | bc)
 
# Log if slow
if (( $(echo "$DURATION > 1.0" | bc -l) )); then
    echo "[SLOW HOOK] $SCRIPT_TO_PROFILE took ${DURATION}s" >> ~/.claude/performance.log
fi
 
exit $RESULT

πŸ€– Subagents Troubleshooting {#subagents}

Common Subagent Issues

1. Task Drift Prevention

// Problem: Subagents ignore boundaries
const preventTaskDrift = `
Task 1: ONLY analyze existing auth code in src/auth/
- DO NOT implement new features
- DO NOT modify any files  
- STOP after creating analysis report
- Return: List of current auth methods and potential issues
`;

2. Context Window Management

// Solution: Context preservation strategy
const contextPreservation = `
1. Main agent creates context-summary.md before spawning subagents
2. Each subagent reads context-summary.md first
3. Subagents write key findings to findings-{taskId}.md
4. Main agent reads all findings files for synthesis
 
Example structure:
/temp
  /context-summary.md     # Created by main agent
  /findings-task1.md      # Created by subagent 1
  /findings-task2.md      # Created by subagent 2
`;

3. Token Consumption Monitoring

// Monitoring pattern
const tokenMonitoring = `
Before using subagents, calculate:
- Base context size: ~X tokens
- Per-subagent overhead: ~Y tokens  
- Number of subagents: N
- Estimated total: (X + Y) * N * 3.5
 
If total > token_budget:
- Reduce number of subagents
- Minimize context per subagent
- Use direct tools instead
`;

4. Deceptive Behavior Detection

// Detection pattern
const deceptionDetection = `
Warning signs:
- Suspiciously fast completion
- Vague or generic results
- No specific file:line references
- Claims of "simulated" outputs
 
Prevention:
1. Request specific file paths and line numbers
2. Ask for exact error messages
3. Require code snippets in responses
4. Validate results with direct tool usage
`;

πŸ”§ Debugging Tools & Utilities

Health Check Script

async function healthCheck() {
  console.log('πŸ₯ Claude Code SDK Health Check\n');
  
  const checks = [
    {
      name: 'Node.js Version',
      check: () => {
        const version = process.version;
        const major = parseInt(version.split('.')[0].slice(1));
        return {
          pass: major >= 18,
          info: `${version} (requires 18+)`
        };
      }
    },
    {
      name: 'API Key',
      check: () => {
        const hasKey = !!process.env.ANTHROPIC_API_KEY;
        return {
          pass: hasKey,
          info: hasKey ? 'Set' : 'Not set'
        };
      }
    },
    {
      name: 'Network Connectivity',
      check: async () => {
        try {
          const response = await fetch('https://api.anthropic.com');
          return {
            pass: response.ok || response.status === 401,
            info: `Status ${response.status}`
          };
        } catch (error) {
          return { pass: false, info: error.message };
        }
      }
    }
  ];
  
  for (const { name, check } of checks) {
    const result = await check();
    const icon = result.pass ? 'βœ…' : '❌';
    console.log(`${icon} ${name}: ${result.info}`);
  }
}

Real-time Monitor

#!/bin/bash
# monitor_claude.sh
 
LOG_FILE="$HOME/.claude/debug.log"
 
clear
echo "Claude Code Monitor"
echo "=================="
echo "Watching: $LOG_FILE"
echo "Press Ctrl+C to exit"
echo ""
 
tail -f "$LOG_FILE" | while read -r line; do
    if [[ "$line" =~ "ERROR" ]]; then
        echo -e "\033[31m$line\033[0m"  # Red
    elif [[ "$line" =~ "WARNING" ]]; then
        echo -e "\033[33m$line\033[0m"  # Yellow
    elif [[ "$line" =~ "SUCCESS" ]]; then
        echo -e "\033[32m$line\033[0m"  # Green
    else
        echo "$line"
    fi
done

πŸ“‹ Quick Reference Commands

Essential Commands

# Installation & Setup
npm install -g @anthropic-ai/claude-code
claude setup-token
export ANTHROPIC_API_KEY="sk-ant-..."
 
# Debugging
claude doctor                   # Check installation
claude --verbose               # Verbose output
claude --mcp-debug             # MCP debugging
/bug                          # Report bug from Claude Code
 
# Fixes
claude migrate-installer       # Fix permissions
npm cache clean --force       # Clear npm cache
rm -rf ~/.claude/cache/*      # Clear Claude cache
 
# Testing
claude -p "Test connection"    # Basic test
tail -f ~/.claude/logs/*      # View logs
cat .claude/settings.json | jq . # Check config

🎯 Troubleshooting Decision Tree

Problem occurs
    β”‚
    β”œβ”€> Authentication issue?
    β”‚      β”œβ”€> Check API key format
    β”‚      β”œβ”€> Regenerate OAuth token
    β”‚      └─> Verify network access
    β”‚
    β”œβ”€> Permission issue?
    β”‚      β”œβ”€> Run migrate-installer
    β”‚      β”œβ”€> Fix npm prefix
    β”‚      └─> Check file permissions
    β”‚
    β”œβ”€> Hook not working?
    β”‚      β”œβ”€> Validate JSON syntax
    β”‚      β”œβ”€> Test matcher pattern
    β”‚      β”œβ”€> Check exit codes
    β”‚      └─> Debug environment
    β”‚
    β”œβ”€> Performance issue?
    β”‚      β”œβ”€> Use streaming
    β”‚      β”œβ”€> Add timeouts
    β”‚      β”œβ”€> Reduce scope
    β”‚      └─> Monitor resources
    β”‚
    └─> Subagent issue?
           β”œβ”€> Check task boundaries
           β”œβ”€> Monitor token usage
           β”œβ”€> Validate outputs
           └─> Use fallback strategies

Component-Specific Guides

General Resources

  • Knowledge Base Overview
  • GitHub Issues: Report bugs
  • Community Forums: Share solutions
  • Documentation: /help in Claude Code

πŸ”„ Maintenance

This MOC consolidates troubleshooting information from:

  • TypeScript SDK documentation
  • Hooks troubleshooting guides
  • Subagents debugging resources
  • Workshop materials

Remember: Most issues are configuration or environment related. Start with simple tests and build up complexity gradually.