Troubleshooting
View SourceThis guide helps you diagnose and resolve common issues with the ClaudeCode Elixir SDK.
Table of Contents
- Installation Issues
- Authentication Problems
- CLI Integration Issues
- Session Management
- Streaming Problems
- Performance Issues
- Error Reference
Installation Issues
ClaudeCode Package Not Found
Problem: mix deps.get
fails to find the ClaudeCode package.
Solution:
# Make sure you're using the correct package name and version
def deps do
[
{:claude_code, "~> 0.1.0"}
]
end
If using a pre-release version:
def deps do
[
{:claude_code, github: "guess/claude_code", branch: "main"}
]
end
Compilation Errors
Problem: ClaudeCode fails to compile with dependency errors.
Common causes:
- Incompatible Elixir/OTP versions
- Missing required dependencies
Solution:
# Check your Elixir version (requires 1.16+)
elixir --version
# Clean and reinstall dependencies
mix deps.clean --all
mix deps.get
mix compile
Authentication Problems
Invalid API Key Error
Problem: Getting authentication errors when starting a session.
Error message:
{:error, {:claude_error, "Authentication failed"}}
Solutions:
Check your API key:
echo $ANTHROPIC_API_KEY
Verify the key format:
# Should start with 'sk-ant-' export ANTHROPIC_API_KEY="sk-ant-your-key-here"
Test with the Claude CLI directly:
claude --version echo "Hello" | claude
Use a different environment variable:
{:ok, session} = ClaudeCode.start_link( api_key: System.get_env("MY_CLAUDE_KEY") )
API Key Not Found
Problem: Session fails to start with missing API key.
Error message:
{:error, "API key is required"}
Solutions:
Set the environment variable:
export ANTHROPIC_API_KEY="your-key-here"
Pass the key directly:
{:ok, session} = ClaudeCode.start_link( api_key: "your-key-here" # Not recommended for production )
Use application config:
# config/config.exs config :claude_code, api_key: System.get_env("ANTHROPIC_API_KEY")
CLI Integration Issues
Claude CLI Not Found
Problem: ClaudeCode can't find the Claude CLI binary.
Error message:
{:error, {:cli_not_found, "claude command not found in PATH"}}
Solutions:
Install the Claude CLI:
- Visit claude.ai/code
- Follow installation instructions for your platform
Verify installation:
which claude claude --version
Add to PATH if needed:
# For bash/zsh export PATH="$PATH:/path/to/claude/bin" # Or create a symlink ln -s /path/to/claude/bin/claude /usr/local/bin/claude
Check PATH configuration:
# Verify claude is in your PATH echo $PATH # Add claude location to PATH if needed export PATH="$PATH:/path/to/claude/directory"
CLI Version Compatibility
Problem: ClaudeCode doesn't work with your Claude CLI version.
Solution:
# Check CLI version
claude --version
# Update to latest version
# Follow update instructions at claude.ai/code
Supported CLI versions: 0.8.0+
CLI Hangs or Times Out
Problem: CLI subprocess hangs or doesn't respond.
Common causes:
- CLI waiting for input
- Network connectivity issues
- CLI process stuck
Solutions:
Check timeout settings:
{:ok, session} = ClaudeCode.start_link( api_key: "...", timeout: 300_000 # 5 minutes )
Test CLI directly:
echo "Hello" | claude --print
Check network connectivity:
curl -I https://api.anthropic.com
Session Management
Session Dies Unexpectedly
Problem: Session GenServer crashes or stops responding.
Debugging steps:
Check session status:
ClaudeCode.alive?(session)
Use supervision (manual setup required):
# ClaudeCode doesn't provide built-in child_spec # You need to create a wrapper or use a simple supervisor defmodule MyApp.ClaudeSupervisor do use Supervisor def start_link(opts) do Supervisor.start_link(__MODULE__, opts, name: __MODULE__) end def init(opts) do children = [ {ClaudeCode, [api_key: "...", name: :claude_session]} ] Supervisor.init(children, strategy: :one_for_one) end end
Session State Corruption
Problem: Session maintains incorrect conversation context.
Solutions:
Clear session state:
ClaudeCode.clear(session)
Restart session:
ClaudeCode.stop(session) {:ok, new_session} = ClaudeCode.start_link(opts)
Use fresh sessions for unrelated queries:
# For isolated queries {:ok, temp_session} = ClaudeCode.start_link(api_key: "...") result = ClaudeCode.query_sync(temp_session, prompt) ClaudeCode.stop(temp_session)
Streaming Problems
Stream Doesn't Start
Problem: Streaming query returns empty stream or never yields data.
Debugging:
Test with synchronous query first:
case ClaudeCode.query_sync(session, prompt) do {:ok, response} -> IO.puts("Sync works: #{response}") error -> IO.puts("Sync error: #{inspect(error)}") end
Check stream consumption:
# Force stream evaluation session |> ClaudeCode.query(prompt) |> Enum.to_list() |> IO.inspect()
Use stream utilities:
session |> ClaudeCode.query(prompt) |> ClaudeCode.Stream.text_content() |> Enum.each(&IO.write/1)
Stream Hangs or Stalls
Problem: Stream starts but stops producing data.
Solutions:
Add timeouts:
session |> ClaudeCode.query(prompt, timeout: 120_000) |> Stream.take_while(fn _ -> true end) |> Enum.to_list()
Use stream debugging:
session |> ClaudeCode.query(prompt) |> Stream.each(fn msg -> IO.inspect(msg, label: "Stream message") end) |> ClaudeCode.Stream.text_content() |> Enum.to_list()
Memory Issues with Large Streams
Problem: Streaming large responses causes memory issues.
Solutions:
Process chunks immediately:
session |> ClaudeCode.query(prompt) |> ClaudeCode.Stream.text_content() |> Stream.each(&IO.write/1) # Don't accumulate |> Stream.run()
Use buffered streaming:
session |> ClaudeCode.query(prompt) |> ClaudeCode.Stream.buffered_text() |> Stream.each(&process_complete_sentences/1) |> Stream.run()
Performance Issues
Slow Query Response
Problem: Queries take too long to respond.
Optimization strategies:
Use appropriate models:
# For simple tasks, use faster models {:ok, session} = ClaudeCode.start_link( api_key: "...", model: "claude-3-haiku-20240307" # Faster model )
Optimize prompts:
# Be specific and concise prompt = "Briefly explain GenServers in 2 paragraphs."
Use streaming for responsiveness:
# User sees response immediately session |> ClaudeCode.query(prompt) |> ClaudeCode.Stream.text_content() |> Enum.each(&IO.write/1)
High Memory Usage
Problem: ClaudeCode uses too much memory.
Solutions:
Limit concurrent sessions:
# Limit the number of concurrent sessions manually # (No built-in session pooling - you need to implement this) max_sessions = System.schedulers_online() # Example: Use Task.async_stream with max_concurrency
Clean up sessions:
# Always stop sessions when done ClaudeCode.stop(session)
Monitor memory usage:
:erlang.memory()
Connection Limits
Problem: Too many concurrent requests to Claude API.
Error message:
{:error, {:claude_error, "Rate limit exceeded"}}
Solutions:
Implement backoff:
defp query_with_backoff(session, prompt, retries \\ 3) do case ClaudeCode.query_sync(session, prompt) do {:ok, response} -> {:ok, response} {:error, {:claude_error, "Rate limit" <> _}} when retries > 0 -> :timer.sleep(2000) # Wait 2 seconds query_with_backoff(session, prompt, retries - 1) error -> error end end
Use fewer concurrent sessions:
# Limit parallelism Task.async_stream(tasks, &process_task/1, max_concurrency: 2)
Error Reference
Common Error Patterns
CLI Errors
{:error, {:cli_not_found, message}} # Claude CLI not installed
{:error, {:cli_exit, exit_code}} # CLI crashed or failed
{:error, {:port_closed, reason}} # Communication failure
Authentication Errors
{:error, {:claude_error, "Invalid API key"}}
{:error, {:claude_error, "Authentication failed"}}
{:error, {:claude_error, "Rate limit exceeded"}}
Session Errors
{:error, :timeout} # Query timed out
{:error, :session_not_found} # Session doesn't exist
{:error, {:invalid_options, details}} # Bad configuration
Stream Errors
{:stream_error, reason} # Generic stream error
{:stream_timeout, request_ref} # Stream timed out
{:stream_init_error, reason} # Failed to start stream
Debugging Commands
Check System Status
# Check if Claude CLI is available
System.cmd("which", ["claude"])
# Test CLI directly
System.cmd("claude", ["--version"])
# Check environment
System.get_env("ANTHROPIC_API_KEY")
# Test network connectivity
System.cmd("curl", ["-I", "https://api.anthropic.com"])
Enable Debug Logging
# Add to config/config.exs
config :logger, :console,
level: :debug,
format: "$time $metadata[$level] $message\n"
# Or in IEx
Logger.configure(level: :debug)
Monitor Resource Usage
# Memory usage
:erlang.memory()
# Process info
Process.info(session_pid)
# System info
:erlang.system_info(:process_count)
Getting Help
If you're still having issues:
- Check the logs - Enable debug logging to see what's happening
- Test components individually - CLI, network, authentication
- Create a minimal reproduction - Isolate the problem
- Check GitHub issues - Someone might have seen this before
- Open an issue - Include logs, environment details, and reproduction steps
Minimal Reproduction Template
# Paste this into IEx to reproduce the issue
alias ClaudeCode
# Your environment
IO.puts("Elixir: #{System.version()}")
IO.puts("OTP: #{System.otp_release()}")
case System.cmd("claude", ["--version"]) do
{output, 0} -> IO.puts("Claude CLI: #{String.trim(output)}")
{error, code} -> IO.puts("Claude CLI error: #{error} (exit: #{code})")
end
# Your code that demonstrates the problem
{:ok, session} = ClaudeCode.start_link(
api_key: System.get_env("ANTHROPIC_API_KEY")
)
# The failing operation
result = ClaudeCode.query_sync(session, "Hello")
IO.inspect(result, label: "Result")
ClaudeCode.stop(session)
Include this output when reporting issues for faster resolution.