Skip to content

Error Codes Reference

This document provides a comprehensive list of error codes returned by BioMCP APIs, their meanings, and recommended actions.

HTTP Status Codes

Success Codes (2xx)

Code Status Description
200 OK Request successful
201 Created Resource created successfully
204 No Content Request successful, no content to return

Client Error Codes (4xx)

Code Status Description Action
400 Bad Request Invalid request parameters Check parameter format and values
401 Unauthorized Missing or invalid API key Verify API key is correct
403 Forbidden Access denied to resource Check permissions for API key
404 Not Found Resource not found Verify ID exists and is correct format
409 Conflict Resource conflict Check for duplicate requests
422 Unprocessable Entity Validation error Review validation errors in response
429 Too Many Requests Rate limit exceeded Implement backoff and retry

Server Error Codes (5xx)

Code Status Description Action
500 Internal Server Error Server error Retry with exponential backoff
502 Bad Gateway Upstream service error Wait and retry
503 Service Unavailable Service temporarily unavailable Check service status, retry later
504 Gateway Timeout Request timeout Retry with smaller request

BioMCP-Specific Error Codes

Article Errors (1xxx)

Code Error Description Example
1001 INVALID_PMID Invalid PubMed ID format "abc123" instead of "12345678"
1002 ARTICLE_NOT_FOUND Article does not exist PMID not in PubMed
1003 DOI_NOT_FOUND DOI cannot be resolved Invalid or non-existent DOI
1004 PUBTATOR_ERROR PubTator3 annotation failed Service temporarily down
1005 PREPRINT_NOT_INDEXED Preprint not yet indexed Recently submitted preprint

Trial Errors (2xxx)

Code Error Description Example
2001 INVALID_NCT_ID Invalid NCT ID format Missing "NCT" prefix
2002 TRIAL_NOT_FOUND Trial does not exist NCT ID not registered
2003 INVALID_LOCATION Invalid geographic coordinates Latitude > 90
2004 NCI_API_REQUIRED NCI API key required Using NCI source without key
2005 INVALID_STATUS Invalid trial status Status not recognized

Variant Errors (3xxx)

Code Error Description Example
3001 INVALID_HGVS Invalid HGVS notation Malformed HGVS string
3002 VARIANT_NOT_FOUND Variant not in database Novel variant
3003 INVALID_ASSEMBLY Invalid genome assembly Not hg19 or hg38
3004 COORDINATE_MISMATCH Coordinates don't match reference Position out of range
3005 ALPHAGENOME_REQUIRED AlphaGenome API key required Prediction without key

Gene/Drug/Disease Errors (4xxx)

Code Error Description Example
4001 GENE_NOT_FOUND Gene symbol not recognized Non-standard symbol
4002 DRUG_NOT_FOUND Drug/chemical not found Misspelled drug name
4003 DISEASE_NOT_FOUND Disease term not recognized Non-standard terminology
4004 SPECIES_NOT_SUPPORTED Only human genes supported Requesting mouse gene
4005 AMBIGUOUS_QUERY Multiple matches found Common drug name

Authentication Errors (5xxx)

Code Error Description Action
5001 API_KEY_INVALID API key format invalid Check key format
5002 API_KEY_EXPIRED API key has expired Renew API key
5003 API_KEY_REVOKED API key was revoked Contact support
5004 INSUFFICIENT_PERMISSIONS API key lacks required permissions Upgrade API key
5005 IP_NOT_ALLOWED IP address not whitelisted Add IP to whitelist

Rate Limit Errors (6xxx)

Code Error Description Headers
6001 RATE_LIMIT_EXCEEDED Too many requests X-RateLimit-Remaining: 0
6002 DAILY_LIMIT_EXCEEDED Daily quota exceeded X-RateLimit-Reset: timestamp
6003 CONCURRENT_LIMIT Too many concurrent requests X-Concurrent-Limit: 10
6004 BURST_LIMIT_EXCEEDED Short-term rate limit Retry-After: 60

Validation Errors (7xxx)

Code Error Description Example
7001 MISSING_REQUIRED_FIELD Required parameter missing Missing gene for variant search
7002 INVALID_FIELD_TYPE Wrong parameter type String instead of integer
7003 VALUE_OUT_OF_RANGE Value outside allowed range Page number < 1
7004 INVALID_ENUM_VALUE Invalid enumeration value Phase "PHASE5"
7005 MUTUALLY_EXCLUSIVE Conflicting parameters Both PMID and DOI provided

External Service Errors (8xxx)

Code Error Description Service
8001 PUBMED_UNAVAILABLE PubMed API down NCBI E-utilities
8002 CLINICALTRIALS_UNAVAILABLE ClinicalTrials.gov down CT.gov API
8003 BIOTHINGS_UNAVAILABLE BioThings API down MyGene/MyVariant
8004 CBIOPORTAL_UNAVAILABLE cBioPortal unavailable cBioPortal API
8005 EXTERNAL_TIMEOUT External service timeout Any external API

Error Response Format

Standard Error Response

{
  "error": {
    "code": 1002,
    "type": "ARTICLE_NOT_FOUND",
    "message": "Article with PMID 99999999 not found",
    "details": {
      "pmid": "99999999",
      "searched_in": ["pubmed", "pmc", "preprints"]
    }
  },
  "request_id": "req_abc123",
  "timestamp": "2024-03-15T10:30:00Z"
}

Validation Error Response

{
  "error": {
    "code": 7001,
    "type": "MISSING_REQUIRED_FIELD",
    "message": "Validation failed",
    "details": {
      "errors": [
        {
          "field": "gene",
          "message": "Gene symbol is required for variant search"
        },
        {
          "field": "assembly",
          "message": "Assembly must be 'hg19' or 'hg38'"
        }
      ]
    }
  }
}

Rate Limit Error Response

{
  "error": {
    "code": 6001,
    "type": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit of 180 requests per minute exceeded",
    "details": {
      "limit": 180,
      "remaining": 0,
      "reset": 1710504000,
      "retry_after": 45
    }
  },
  "headers": {
    "X-RateLimit-Limit": "180",
    "X-RateLimit-Remaining": "0",
    "X-RateLimit-Reset": "1710504000",
    "Retry-After": "45"
  }
}

Error Handling Best Practices

1. Implement Exponential Backoff

import time
import random

def exponential_backoff(attempt: int, base_delay: float = 1.0):
    """Calculate exponential backoff with jitter."""
    delay = base_delay * (2 ** attempt)
    jitter = random.uniform(0, delay * 0.1)
    return delay + jitter

# Usage
for attempt in range(5):
    try:
        response = await client.search(...)
        break
    except RateLimitError:
        delay = exponential_backoff(attempt)
        time.sleep(delay)

2. Handle Specific Error Types

try:
    article = await client.articles.get(pmid)
except BioMCPError as e:
    if e.code == 1002:  # ARTICLE_NOT_FOUND
        # Try alternative sources
        article = await search_preprints(pmid)
    elif e.code == 6001:  # RATE_LIMIT_EXCEEDED
        # Wait and retry
        time.sleep(e.retry_after)
        article = await client.articles.get(pmid)
    else:
        # Log and re-raise
        logger.error(f"Unexpected error: {e}")
        raise

3. Parse Error Details

def handle_validation_error(error_response):
    """Extract and handle validation errors."""
    if error_response["error"]["type"] == "VALIDATION_ERROR":
        for error in error_response["error"]["details"]["errors"]:
            field = error["field"]
            message = error["message"]
            print(f"Validation error on {field}: {message}")

4. Monitor Rate Limits

class RateLimitMonitor:
    def __init__(self):
        self.limits = {}

    def update_from_headers(self, headers):
        """Update rate limit state from response headers."""
        self.limits["remaining"] = int(headers.get("X-RateLimit-Remaining", 0))
        self.limits["reset"] = int(headers.get("X-RateLimit-Reset", 0))

        if self.limits["remaining"] < 10:
            logger.warning(f"Rate limit low: {self.limits['remaining']} remaining")

    def should_delay(self):
        """Check if we should delay before next request."""
        return self.limits.get("remaining", 100) < 5

Common Error Scenarios

Scenario 1: Gene Symbol Not Found

Error:

{
  "error": {
    "code": 4001,
    "type": "GENE_NOT_FOUND",
    "message": "Gene symbol 'HER2' not found. Did you mean 'ERBB2'?",
    "details": {
      "query": "HER2",
      "suggestions": ["ERBB2", "ERBB2IP"]
    }
  }
}

Solution:

try:
    gene = await client.genes.get("HER2")
except GeneNotFoundError as e:
    if e.suggestions:
        # Try first suggestion
        gene = await client.genes.get(e.suggestions[0])

Scenario 2: Location Search Without Coordinates

Error:

{
  "error": {
    "code": 7001,
    "type": "MISSING_REQUIRED_FIELD",
    "message": "Latitude and longitude required for location search",
    "details": {
      "hint": "Use geocoding service to convert city names to coordinates"
    }
  }
}

Solution:

# Use a geocoding service first
coords = await geocode("Boston, MA")
trials = await client.trials.search(
    conditions=["cancer"],
    lat=coords.lat,
    long=coords.long,
    distance=50
)

Scenario 3: API Key Required

Error:

{
  "error": {
    "code": 2004,
    "type": "NCI_API_REQUIRED",
    "message": "NCI API key required for this operation",
    "details": {
      "get_key_url": "https://api.cancer.gov",
      "feature": "biomarker_search"
    }
  }
}

Solution:

# Initialize client with API key
client = BioMCPClient(nci_api_key=os.getenv("NCI_API_KEY"))

# Or provide per-request
trials = await client.trials.search(
    source="nci",
    conditions=["melanoma"],
    api_key="your-nci-key"
)

Debugging Tips

1. Enable Debug Logging

import logging

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("biomcp")

2. Inspect Raw Responses

# Enable raw response mode
client = BioMCPClient(debug=True)

# Access raw response
response = await client.articles.search(genes=["BRAF"])
print(response.raw_response)

3. Capture Request IDs

try:
    result = await client.search(...)
except BioMCPError as e:
    print(f"Request ID: {e.request_id}")
    # Include request_id when reporting issues

Support

For error codes not listed here or persistent issues:

  1. Check FAQ for common issues
  2. Search GitHub Issues
  3. Report new issues with:
  4. Error code and message
  5. Request ID if available
  6. Minimal code to reproduce
  7. BioMCP version