Skip to main content
This guide covers common issues you might encounter when using the HopX API and how to resolve them.

Authentication Issues

Invalid API key

Problem: Receiving 401 Unauthorized errors.
{
  "error": "Invalid API key",
  "code": "AUTHENTICATION_REQUIRED"
}
Solutions:
  1. Verify your API key is correct
  2. Check the Authorization header format: Authorization: Bearer $HOPX_API_KEY
  3. Ensure no extra spaces or newlines in the API key
  4. Generate a new API key from the dashboard
# Correct
curl https://api.hopx.dev/v1/sandboxes \
  -H "Authorization: Bearer sk-live-abc123xyz"

# Wrong - missing "Bearer"
curl https://api.hopx.dev/v1/sandboxes \
  -H "Authorization: sk-live-abc123xyz"

Expired JWT Token

Problem: VM Agent API returns 401 with expired token error. Solution: Refresh the JWT token using the Control Plane API:
curl -X POST https://api.hopx.dev/v1/sandboxes/{sandbox_id}/refresh \
  -H "Authorization: Bearer $HOPX_API_KEY"

Sandbox Creation Issues

Sandbox Stuck in “Creating” Status

Problem: Sandbox status remains “creating” for more than 2 minutes. Solutions:
  1. Wait up to 5 minutes for large templates
  2. Check template status - ensure it’s “active”
  3. Try a different region if available
  4. Delete and recreate the sandbox
# Check sandbox status
curl https://api.hopx.dev/v1/sandboxes/{sandbox_id} \
  -H "Authorization: Bearer $HOPX_API_KEY" | jq '.status'

# If stuck, delete and recreate
curl -X DELETE https://api.hopx.dev/v1/sandboxes/{sandbox_id} \
  -H "Authorization: Bearer $HOPX_API_KEY"

Template Not Found

Problem: 404 Template not found when creating sandbox.
{
  "error": "Template not found",
  "code": "RESOURCE_NOT_FOUND"
}
Solutions:
  1. List available templates to find valid IDs
  2. Use template name instead of ID
  3. Check if template is active
# List available templates
curl https://api.hopx.dev/v1/templates \
  -H "Authorization: Bearer $HOPX_API_KEY" | jq '.data[] | {id, name, is_active}'

# Use name instead of ID
curl -X POST https://api.hopx.dev/v1/sandboxes \
  -H "Authorization: Bearer $HOPX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"template_id": "code-interpreter"}'

Resource Limits Exceeded

Problem: Cannot create more sandboxes.
{
  "error": "Sandbox limit reached (10/10)",
  "code": "RESOURCE_LIMIT_ERROR"
}
Solutions:
  1. Delete unused sandboxes
  2. Upgrade your plan for higher limits
  3. Use sandbox pooling/reuse
# List all sandboxes
curl https://api.hopx.dev/v1/sandboxes \
  -H "Authorization: Bearer $HOPX_API_KEY"

# Delete stopped sandboxes
for ID in $(curl -s https://api.hopx.dev/v1/sandboxes \
  -H "Authorization: Bearer $HOPX_API_KEY" | \
  jq -r '.data[] | select(.status == "stopped") | .id'); do
  curl -X DELETE "https://api.hopx.dev/v1/sandboxes/$ID" \
    -H "Authorization: Bearer $HOPX_API_KEY"
done

Code Execution Issues

Execution Timeout

Problem: Code execution times out.
{
  "error": "Execution timeout after 60 seconds",
  "code": "EXECUTION_TIMEOUT"
}
Solutions:
  1. Increase the timeout parameter
  2. Optimize your code
  3. Use background execution for long tasks
# Increase timeout
curl -X POST https://sandbox_abc123xyz.hopx.dev/execute \
  -H "Authorization: Bearer JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "import time; time.sleep(120)",
    "language": "python",
    "timeout": 180
  }'

# Or use background execution
curl -X POST https://sandbox_abc123xyz.hopx.dev/execute/background \
  -H "Authorization: Bearer JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "import time; time.sleep(600)",
    "language": "python",
    "timeout": 900
  }'

Import/Module Errors

Problem: Python packages not found.
ModuleNotFoundError: No module named 'requests'
Solutions:
  1. Install packages before use
  2. Use a template with pre-installed packages
  3. Check package spelling
# Install package first
curl -X POST https://sandbox_abc123xyz.hopx.dev/commands/run \
  -H "Authorization: Bearer JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "command": "pip install requests numpy pandas",
    "timeout": 120
  }'

# Then use it
curl -X POST https://sandbox_abc123xyz.hopx.dev/execute \
  -H "Authorization: Bearer JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "import requests; print(requests.__version__)",
    "language": "python"
  }'

File Operation Issues

Path Not Allowed

Problem: 403 Forbidden when accessing files.
{
  "error": "Path not allowed: /etc/passwd",
  "code": "FORBIDDEN"
}
Solutions:
  1. Only access allowed paths: /workspace, /tmp
  2. Use relative paths from allowed directories
# Good - allowed paths
curl "https://sandbox_abc123xyz.hopx.dev/files/read?path=/workspace/data.txt" \
  -H "Authorization: Bearer JWT_TOKEN"

# Bad - forbidden path
curl "https://sandbox_abc123xyz.hopx.dev/files/read?path=/etc/passwd" \
  -H "Authorization: Bearer JWT_TOKEN"

File Not Found

Problem: File doesn’t exist when trying to read. Solutions:
  1. Check if file exists first
  2. Create the file before reading
  3. Verify the file path
# Check if file exists
EXISTS=$(curl -s "https://sandbox_abc123xyz.hopx.dev/files/exists?path=/workspace/data.txt" \
  -H "Authorization: Bearer JWT_TOKEN" | jq -r '.exists')

if [ "$EXISTS" == "true" ]; then
  # File exists, read it
  curl "https://sandbox_abc123xyz.hopx.dev/files/read?path=/workspace/data.txt" \
    -H "Authorization: Bearer JWT_TOKEN"
else
  # File doesn't exist, create it
  curl -X POST https://sandbox_abc123xyz.hopx.dev/files/write \
    -H "Authorization: Bearer JWT_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "path": "/workspace/data.txt",
      "content": "Initial content"
    }'
fi

Connection Issues

Network Timeout

Problem: Requests timing out. Solutions:
  1. Increase client timeout
  2. Check network connectivity
  3. Use retry logic with exponential backoff
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# Configure retries
session = requests.Session()
retries = Retry(
    total=5,
    backoff_factor=1,
    status_forcelist=[502, 503, 504]
)
session.mount('https://', HTTPAdapter(max_retries=retries))

# Make request with retries
response = session.post(
    "https://api.hopx.dev/v1/sandboxes",
    headers={"Authorization": "Bearer $HOPX_API_KEY"},
    json={"template_id": "code-interpreter"},
    timeout=30
)

SSL Certificate Errors

Problem: SSL verification failures. Solutions:
  1. Update your SSL certificates
  2. Update your HTTP client library
  3. Check system time (certificate validation depends on correct time)
# Update certificates (Ubuntu/Debian)
sudo apt-get update
sudo apt-get install ca-certificates

# Update Python certifi
pip install --upgrade certifi

Rate Limiting

Rate Limit Exceeded

Problem: 429 Too Many Requests errors.
{
  "error": "Rate limit exceeded: 100 requests per minute",
  "code": "RATE_LIMIT_EXCEEDED",
  "retry_after": 30
}
Solutions:
  1. Implement exponential backoff
  2. Respect the retry_after header
  3. Distribute requests over time
  4. Cache responses when possible
import time
import requests

def make_request_with_rate_limiting(url, headers):
    max_retries = 5
    
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)
        
        if response.status_code != 429:
            return response
        
        # Get retry_after from header or response body
        retry_after = int(response.headers.get('Retry-After', 0))
        if retry_after == 0:
            error_data = response.json()
            retry_after = error_data.get('retry_after', 2 ** attempt)
        
        print(f"Rate limited. Waiting {retry_after}s")
        time.sleep(retry_after)
    
    raise Exception("Max retries exceeded")

Debugging Tips

Enable Verbose Logging

# cURL with verbose output
curl -v https://api.hopx.dev/v1/sandboxes \
  -H "Authorization: Bearer $HOPX_API_KEY"

# Python with logging
import logging
import requests

logging.basicConfig(level=logging.DEBUG)
response = requests.get(
    "https://api.hopx.dev/v1/sandboxes",
    headers={"Authorization": "Bearer $HOPX_API_KEY"}
)

Check Request ID

Every response includes a request_id for debugging:
curl -i https://api.hopx.dev/v1/sandboxes \
  -H "Authorization: Bearer $HOPX_API_KEY" | grep request_id
Include the request_id when contacting support.

Inspect Full Response

# Save full response for debugging
curl -i https://api.hopx.dev/v1/sandboxes \
  -H "Authorization: Bearer $HOPX_API_KEY" \
  > response.txt

Test with cURL First

Before implementing in your application, test with cURL:
# Test sandbox creation
curl -X POST https://api.hopx.dev/v1/sandboxes \
  -H "Authorization: Bearer $HOPX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"template_id": "code-interpreter"}' | jq '.'

Getting Help

If you’re still experiencing issues:
  1. Check Status Page - https://status.hopx.dev
  2. Review Documentation - Complete API reference
  3. Contact Support - Include:
    • Request ID
    • Timestamp
    • Full error message
    • Code snippet (remove sensitive data)
    • Expected vs actual behavior

Common Patterns

Healthcheck Pattern

def check_sandbox_health(sandbox_id, jwt_token):
    """Check if sandbox is ready for use"""
    try:
        response = requests.get(
            f"https://{sandbox_id}.hopx.dev/health",
            headers={"Authorization": f"Bearer {jwt_token}"},
            timeout=5
        )
        return response.status_code == 200
    except:
        return False

Cleanup Pattern

def cleanup_old_sandboxes(api_key, hours=24):
    """Delete sandboxes older than specified hours"""
    from datetime import datetime, timedelta
    
    response = requests.get(
        "https://api.hopx.dev/v1/sandboxes",
        headers={"Authorization": f"Bearer {api_key}"}
    )
    
    cutoff = datetime.utcnow() - timedelta(hours=hours)
    
    for sandbox in response.json()["data"]:
        created_at = datetime.fromisoformat(sandbox["created_at"].replace('Z', '+00:00'))
        
        if created_at < cutoff:
            print(f"Deleting old sandbox: {sandbox['id']}")
            requests.delete(
                f"https://api.hopx.dev/v1/sandboxes/{sandbox['id']}",
                headers={"Authorization": f"Bearer {api_key}"}
            )

Next Steps