Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.hopx.ai/llms.txt

Use this file to discover all available pages before exploring further.

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