Files
gh-jezweb-claude-skills-ski…/references/top-errors.md
2025-11-30 08:23:58 +08:00

9.8 KiB

Top Errors & Solutions

Complete reference for common Claude Agent SDK errors and how to fix them.


Error #1: CLI Not Found

Error Message

"Claude Code CLI not installed"

Why It Happens

The SDK requires Claude Code CLI to be installed globally, but it's not found in PATH.

Solution

npm install -g @anthropic-ai/claude-code

Verify installation:

which claude-code
# Should output: /usr/local/bin/claude-code or similar

Prevention

  • Install CLI before using SDK
  • Add to project setup documentation
  • Check CLI availability in CI/CD

Error #2: Authentication Failed

Error Message

"Invalid API key"
"Authentication failed"

Why It Happens

  • ANTHROPIC_API_KEY environment variable not set
  • API key is invalid or expired
  • API key has wrong format

Solution

# Set API key
export ANTHROPIC_API_KEY="sk-ant-..."

# Verify it's set
echo $ANTHROPIC_API_KEY

Get API key:

  1. Visit https://console.anthropic.com/
  2. Navigate to API Keys section
  3. Create new key
  4. Copy and save securely

Prevention

  • Use environment variables (never hardcode)
  • Check key before running
  • Add to .env.example template
  • Document setup process

Error #3: Permission Denied

Error Message

"Tool use blocked"
"Permission denied for tool: Bash"

Why It Happens

  • Tool not in allowedTools array
  • permissionMode is too restrictive
  • Custom canUseTool callback denied execution

Solution

// Add tool to allowedTools
options: {
  allowedTools: ["Read", "Write", "Edit", "Bash"]  // Add needed tools
}

// Or use less restrictive permission mode
options: {
  permissionMode: "acceptEdits"  // Auto-approve edits
}

// Or check canUseTool logic
options: {
  canUseTool: async (toolName, input) => {
    console.log("Tool requested:", toolName);  // Debug
    return { behavior: "allow" };
  }
}

Prevention

  • Set appropriate allowedTools from start
  • Test permission logic thoroughly
  • Use permissionMode: "bypassPermissions" in CI/CD

Error #4: Context Length Exceeded

Error Message

"Prompt too long"
"Context length exceeded"
"Too many tokens"

Why It Happens

  • Input prompt exceeds model's context window (200k tokens)
  • Long conversation without pruning
  • Large files in context

Solution

SDK auto-compacts context, but you can:

// Fork session to start fresh from a point
const forked = query({
  prompt: "Continue with fresh context",
  options: {
    resume: sessionId,
    forkSession: true  // Start fresh
  }
});

// Or reduce context
options: {
  allowedTools: ["Read", "Grep"],  // Limit tools
  systemPrompt: "Keep responses concise."
}

Prevention

  • Use session forking for long tasks
  • Keep prompts focused
  • Don't load unnecessary files
  • Monitor context usage

Error #5: Tool Execution Timeout

Error Message

"Tool did not respond"
"Tool execution timeout"

Why It Happens

  • Tool takes too long (>5 minutes default)
  • Infinite loop in tool implementation
  • Network timeout for external tools

Solution

For custom tools:

tool("long_task", "Description", schema, async (args) => {
  // Add timeout
  const timeout = 60000; // 1 minute
  const promise = performLongTask(args);
  const result = await Promise.race([
    promise,
    new Promise((_, reject) =>
      setTimeout(() => reject(new Error('Timeout')), timeout)
    )
  ]);
  return { content: [{ type: "text", text: result }] };
})

For bash commands:

// Add timeout to bash command
command: "timeout 60s long-running-command"

Prevention

  • Set reasonable timeouts
  • Optimize tool implementations
  • Use background jobs for long tasks
  • Test tools independently

Error #6: Session Not Found

Error Message

"Invalid session ID"
"Session not found"

Why It Happens

  • Session ID is incorrect
  • Session expired (old)
  • Session from different CLI instance

Solution

// Ensure session ID captured correctly
let sessionId: string | undefined;
for await (const message of response) {
  if (message.type === 'system' && message.subtype === 'init') {
    sessionId = message.session_id;  // Capture here
    console.log("Session:", sessionId);  // Verify
  }
}

// Use correct session ID
query({
  prompt: "...",
  options: { resume: sessionId }  // Must match exactly
});

Prevention

  • Always capture session_id from system init
  • Store session IDs reliably
  • Don't rely on sessions lasting indefinitely
  • Handle session errors gracefully

Error #7: MCP Server Connection Failed

Error Message

"Server connection error"
"MCP server not responding"
"Failed to connect to MCP server"

Why It Happens

  • Server command/URL incorrect
  • Server crashed or not running
  • Network issues (HTTP/SSE servers)
  • Missing dependencies

Solution

For stdio servers:

// Verify command works independently
// Test: npx @modelcontextprotocol/server-filesystem
options: {
  mcpServers: {
    "filesystem": {
      command: "npx",  // Verify npx is available
      args: ["@modelcontextprotocol/server-filesystem"],
      env: {
        ALLOWED_PATHS: "/path"  // Verify path exists
      }
    }
  }
}

For HTTP servers:

// Test URL separately
const testResponse = await fetch("https://api.example.com/mcp");
console.log(testResponse.status);  // Should be 200

Prevention

  • Test MCP servers independently before integration
  • Verify command/URL works
  • Add error handling for server failures
  • Use health checks

Error #8: Subagent Definition Error

Error Message

"Invalid AgentDefinition"
"Agent configuration error"

Why It Happens

  • Missing required fields (description or prompt)
  • Invalid model value
  • Invalid tools array

Solution

agents: {
  "my-agent": {
    description: "Clear description of when to use",  // Required
    prompt: "Detailed system prompt",                  // Required
    tools: ["Read", "Write"],                          // Optional
    model: "sonnet"                                    // Optional
  }
}

Prevention

  • Always include description and prompt
  • Use TypeScript types
  • Test agent definitions
  • Follow examples in templates

Error #9: Settings File Not Found

Error Message

"Cannot read settings"
"Settings file not found"

Why It Happens

  • settingSources includes non-existent file
  • File path incorrect
  • File permissions deny read

Solution

// Check file exists before loading
import fs from 'fs';

const projectSettingsPath = '.claude/settings.json';
const settingSources = [];

if (fs.existsSync(projectSettingsPath)) {
  settingSources.push('project');
}

options: {
  settingSources  // Only existing files
}

Prevention

  • Check file exists before including in sources
  • Use empty array for isolated execution
  • Handle missing files gracefully

Error #10: Tool Name Collision

Error Message

"Duplicate tool name"
"Tool already defined"

Why It Happens

  • Two MCP servers define same tool name
  • Tool name conflicts with built-in tool

Solution

// Use unique tool names
const server1 = createSdkMcpServer({
  name: "service-a",
  tools: [
    tool("service_a_process", ...)  // Prefix with server name
  ]
});

const server2 = createSdkMcpServer({
  name: "service-b",
  tools: [
    tool("service_b_process", ...)  // Different name
  ]
});

Prevention

  • Use unique tool names
  • Prefix tools with server name
  • Test integration before deployment

Error #11: Zod Schema Validation Error

Error Message

"Invalid tool input"
"Schema validation failed"

Why It Happens

  • Agent provided data that doesn't match Zod schema
  • Schema too restrictive
  • Missing .describe() on fields

Solution

// Add descriptive schemas
{
  email: z.string().email().describe("User email address"),
  age: z.number().int().min(0).max(120).describe("Age in years"),
  role: z.enum(["admin", "user"]).describe("User role")
}

// Make fields optional if appropriate
{
  email: z.string().email(),
  phoneOptional: z.string().optional()  // Not required
}

Prevention

  • Use .describe() on all fields
  • Add validation constraints
  • Test with various inputs
  • Make optional fields explicit

Error #12: Filesystem Permission Denied

Error Message

"Access denied"
"Cannot access path"
"EACCES: permission denied"

Why It Happens

  • Path outside workingDirectory
  • No read/write permissions
  • Protected system directory

Solution

// Set correct working directory
options: {
  workingDirectory: "/path/to/accessible/dir"
}

// Or fix permissions
// chmod +r file.txt  (add read)
// chmod +w file.txt  (add write)

Prevention

  • Set appropriate workingDirectory
  • Verify file permissions
  • Don't access system directories
  • Use dedicated project directories

General Error Handling Pattern

try {
  const response = query({ prompt: "...", options: { ... } });

  for await (const message of response) {
    if (message.type === 'error') {
      console.error('Agent error:', message.error);
      // Handle non-fatal errors
    }
  }
} catch (error) {
  console.error('Fatal error:', error);

  // Handle specific errors
  switch (error.code) {
    case 'CLI_NOT_FOUND':
      console.error('Install: npm install -g @anthropic-ai/claude-code');
      break;
    case 'AUTHENTICATION_FAILED':
      console.error('Check ANTHROPIC_API_KEY');
      break;
    case 'RATE_LIMIT_EXCEEDED':
      console.error('Rate limited. Retry with backoff.');
      break;
    case 'CONTEXT_LENGTH_EXCEEDED':
      console.error('Reduce context or fork session');
      break;
    default:
      console.error('Unexpected error:', error);
  }
}

For more details: See SKILL.md Template: templates/error-handling.ts