| name | openevidence-common-errors |
| description | Diagnose and resolve common OpenEvidence API errors.
Use when encountering error codes, debugging failed requests,
or implementing error handling for clinical queries.
Trigger with phrases like "openevidence error", "openevidence failing",
"fix openevidence", "openevidence debug", "openevidence 4xx", "openevidence 5xx".
|
| allowed-tools | Read, Write, Edit, Grep |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
OpenEvidence Common Errors
Overview
Comprehensive guide to diagnosing and resolving OpenEvidence API errors with healthcare-specific considerations.
Prerequisites
- OpenEvidence SDK installed
- Access to application logs
- Understanding of HTTP status codes
Error Code Reference
Authentication Errors (4xx)
| Code | Error | Cause | Solution |
|---|
| 401 | Invalid API Key | Key missing, malformed, or revoked | Verify OPENEVIDENCE_API_KEY is set correctly |
| 401 | Organization Not Found | Invalid orgId | Check organization ID in dashboard |
| 401 | BAA Not Signed | Business Associate Agreement required | Contact compliance@openevidence.com |
| 403 | Forbidden | Insufficient permissions or suspended account | Check account status in dashboard |
| 403 | IP Not Whitelisted | Request from non-approved IP | Add IP to allowlist in security settings |
Request Errors (4xx)
| Code | Error | Cause | Solution |
|---|
| 400 | Invalid Query | Malformed request body | Check request schema |
| 400 | Query Too Short | Question too brief | Provide more clinical context |
| 400 | Invalid Specialty | Unknown specialty code | Use valid specialty from enum |
| 404 | Resource Not Found | Invalid consultId or endpoint | Verify ID and URL |
| 422 | Unprocessable | Valid JSON but invalid clinical query | Rephrase question |
| 429 | Rate Limited | Too many requests | Implement backoff, check quotas |
Server Errors (5xx)
| Code | Error | Cause | Solution |
|---|
| 500 | Internal Server Error | OpenEvidence backend issue | Retry with backoff, contact support if persists |
| 502 | Bad Gateway | Upstream service issue | Wait and retry |
| 503 | Service Unavailable | Maintenance or overload | Check status.openevidence.com |
| 504 | Gateway Timeout | Request took too long | Simplify query, increase timeout |
Error Handling Implementation
Step 1: Custom Error Classes
export class OpenEvidenceError extends Error {
constructor(
message: string,
public readonly code: string,
public readonly statusCode: number,
public readonly retryable: boolean,
public readonly originalError?: Error
) {
super(message);
this.name = 'OpenEvidenceError';
}
static fromApiError(error: any): OpenEvidenceError {
const statusCode = error.response?.status || 500;
const message = error.response?.data?.message || error.message;
const code = error.response?.data?.code || 'UNKNOWN_ERROR';
return new OpenEvidenceError(
message,
code,
statusCode,
(statusCode),
error
);
}
}
{
() {
(message, code, , );
. = ;
}
}
{
() {
(message, , , );
. = ;
}
}
{
() {
(message, , , );
. = ;
}
}
(): {
statusCode === || statusCode >= ;
}
Step 2: Error Handler Wrapper
import {
OpenEvidenceError,
AuthenticationError,
RateLimitError,
QueryValidationError,
} from './errors';
export async function withErrorHandling<T>(
operation: () => Promise<T>,
context?: { operation?: string; queryId?: string }
): Promise<T> {
try {
return await operation();
} catch (error: any) {
const oeError = classifyError(error);
console.error(`[OpenEvidence Error]`, {
code: oeError.code,
statusCode: oeError.statusCode,
operation: context?.operation,
retryable: oeError.retryable,
});
throw oeError;
}
}
function classifyError(error: any): OpenEvidenceError {
const status = error.response?.;
data = error.?.;
(status) {
:
(
data?. || ,
data?. ||
);
:
(
,
(error.?.?.[] || ),
(error.?.?.[] || ),
(error.?.?.[] || )
);
:
:
(
data?. || ,
data?. || []
);
:
.(error);
}
}
Step 3: Retry Logic with Exponential Backoff
import { OpenEvidenceError, RateLimitError } from './errors';
interface RetryConfig {
maxRetries: number;
baseDelayMs: number;
maxDelayMs: number;
jitterMs: number;
}
const DEFAULT_CONFIG: RetryConfig = {
maxRetries: 3,
baseDelayMs: 1000,
maxDelayMs: 30000,
jitterMs: 500,
};
export async function withRetry<T>(
operation: () => Promise<T>,
config: Partial<RetryConfig> = {}
): Promise<T> {
const cfg = { ...DEFAULT_CONFIG, ...config };
for (let attempt = 0; attempt <= cfg.maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
if (!(error instanceof OpenEvidenceError) || !error.) {
error;
}
(attempt === cfg.) {
error;
}
: ;
(error && error. > ) {
delay = error. * ;
} {
delay = .(
cfg. * .(, attempt) + .() * cfg.,
cfg.
);
}
.();
( (r, delay));
}
}
();
}
Step 4: User-Facing Error Messages
import { OpenEvidenceError, RateLimitError, QueryValidationError } from './errors';
export function getUserFriendlyMessage(error: OpenEvidenceError): string {
switch (error.code) {
case 'AUTH_FAILED':
case 'INVALID_API_KEY':
return 'Unable to connect to medical evidence service. Please contact support.';
case 'BAA_REQUIRED':
return 'Service configuration required. Please contact your administrator.';
case 'RATE_LIMITED':
const rle = error as RateLimitError;
return `Service temporarily unavailable. Please try again in ${rle.retryAfter} seconds.`;
case 'VALIDATION_ERROR':
const qve = error as QueryValidationError;
return `Please rephrase your clinical question. ${qve.validationErrors.join('. ')}`;
case 'QUERY_TOO_SHORT':
return 'Please provide more details about your clinical question.';
:
;
:
;
:
(error. >= ) {
;
}
;
}
}
Output
- Classified errors with appropriate handling
- Retry logic for transient failures
- User-friendly error messages
- Comprehensive error logging (without PHI)
Diagnostic Commands
Quick Health Check
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer ${OPENEVIDENCE_API_KEY}" \
https://api.openevidence.com/health
Check Rate Limit Status
curl -s -D - \
-H "Authorization: Bearer ${OPENEVIDENCE_API_KEY}" \
https://api.openevidence.com/v1/rate-limit \
| grep -i "x-ratelimit"
Error Handling
| Error Pattern | Detection | Resolution |
|---|
| Intermittent 5xx | > 5% error rate | Enable circuit breaker |
| Persistent 401 | All requests fail | Rotate API key |
| Spike in 429 | Rate limit headers | Implement request queuing |
| Timeout errors | P99 > 30s | Check network, simplify queries |
Examples
Complete Error-Handled Query
async function safeClinicalQuery(question: string) {
try {
return await withRetry(
() => withErrorHandling(
() => client.query({ question, context: { specialty: 'internal-medicine', urgency: 'routine' } }),
{ operation: 'clinical-query' }
),
{ maxRetries: 3 }
);
} catch (error) {
if (error instanceof OpenEvidenceError) {
return {
success: false,
error: getUserFriendlyMessage(error),
code: error.code,
};
}
throw error;
}
}
Resources
Next Steps
For comprehensive debugging, see openevidence-debug-bundle.