Appearance
Error Handling
DialogueDB uses standardized error responses to help you handle failures gracefully and build robust applications.
Error Response Format
All error responses follow a consistent structure:
json
{
"error": {
"code": "DIALOGUE_NOT_FOUND",
"message": "Dialogue 'dlg_abc123' not found",
"type": "not_found",
"details": [
{
"field": "id",
"code": "NOT_FOUND",
"message": "Resource does not exist"
}
],
"requestId": "req_xyz789",
"timestamp": "2025-11-06T21:34:21.117Z"
}
}Error Object Fields
| Field | Type | Description |
|---|---|---|
code | string | Machine-readable error code (e.g., DIALOGUE_NOT_FOUND) |
message | string | Human-readable error description |
type | string | Error category: validation_error, not_found, conflict, rate_limit, server |
details | array | Optional field-level validation errors |
requestId | string | Unique request identifier for debugging |
timestamp | string | ISO 8601 timestamp when the error occurred |
HTTP Status Codes
DialogueDB uses standard HTTP status codes to indicate the type of error:
| Status | Meaning | When Used |
|---|---|---|
| 400 | Bad Request | Validation errors, missing required fields, invalid input |
| 401 | Unauthorized | Missing or invalid authentication token |
| 404 | Not Found | Resource (dialogue, message, project) does not exist |
| 409 | Conflict | Resource conflict (e.g., dialogue immutability violation) |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Unexpected server error |
Error Types
Validation Errors (400)
Returned when request data is invalid or missing required fields.
Example:
json
{
"error": {
"code": "MISSING_PARAMETER",
"message": "Missing required parameter: id",
"type": "validation_error",
"details": [
{
"field": "id",
"code": "REQUIRED",
"message": "Dialogue ID is required"
}
],
"requestId": "req_123",
"timestamp": "2025-11-06T21:34:21Z"
}
}Common validation error codes:
MISSING_PARAMETER- Required parameter not providedINVALID_PARAMETER- Parameter format is invalidMESSAGE_CONTENT_EMPTY- Message content cannot be emptyMESSAGE_TOO_LARGE- Message exceeds size limitTOO_MANY_MESSAGES- Exceeds 50 message limit on creationINVALID_MESSAGE_ARRAY- Messages must be an arrayINVALID_ACTION- Unsupported action specified
Not Found Errors (404)
Returned when a requested resource does not exist.
Example:
json
{
"error": {
"code": "DIALOGUE_NOT_FOUND",
"message": "Dialogue 'dlg_abc123' not found",
"type": "not_found",
"requestId": "req_456",
"timestamp": "2025-11-06T21:34:21Z"
}
}Common not found error codes:
DIALOGUE_NOT_FOUND- Dialogue does not existMESSAGE_NOT_FOUND- Message does not existPROJECT_NOT_FOUND- Project does not existPARENT_DIALOGUE_NOT_FOUND- Parent dialogue for thread not found
Conflict Errors (409)
Returned when operation conflicts with resource state.
Example:
json
{
"error": {
"code": "DIALOGUE_IMMUTABLE",
"message": "Cannot delete message: dialogues are immutable in this project",
"type": "conflict",
"requestId": "req_789",
"timestamp": "2025-11-06T21:34:21Z"
}
}Common conflict error codes:
DIALOGUE_IMMUTABLE- Operation not allowed on immutable dialogueDUPLICATE_ID- Resource with this ID already existsRESOURCE_CONFLICT- Operation conflicts with resource state
Rate Limit Errors (429)
Returned when API rate limits are exceeded.
Example:
json
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Please try again later.",
"type": "rate_limit",
"requestId": "req_999",
"timestamp": "2025-11-06T21:34:21Z"
}
}Response headers:
http
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640000060
Retry-After: 60Server Errors (500)
Returned for unexpected server-side errors.
Example:
json
{
"error": {
"code": "INTERNAL_ERROR",
"message": "An internal error occurred while processing your request",
"type": "server",
"requestId": "req_555",
"timestamp": "2025-11-06T21:34:21Z"
}
}Error Code Reference
Validation Errors (400)
| Code | HTTP Status | Description |
|---|---|---|
MISSING_PARAMETER | 400 | Required parameter missing from request |
INVALID_PARAMETER | 400 | Parameter format or value is invalid |
INVALID_INPUT | 400 | Input validation failed |
VALIDATION_ERROR | 400 | General validation error |
MESSAGE_CONTENT_EMPTY | 400 | Message content cannot be empty |
MESSAGE_TOO_LARGE | 400 | Message exceeds maximum size (1MB uncompressed) |
TOO_MANY_MESSAGES | 400 | Exceeds 50 message limit on creation |
INVALID_MESSAGE_ARRAY | 400 | Messages parameter must be an array |
EMPTY_MESSAGE_ARRAY | 400 | Messages array cannot be empty |
INVALID_ACTION | 400 | Unsupported action specified |
SEARCH_QUERY_TOO_SHORT | 400 | Search query must be at least 3 characters |
Not Found Errors (404)
| Code | HTTP Status | Description |
|---|---|---|
DIALOGUE_NOT_FOUND | 404 | Dialogue with specified ID not found |
MESSAGE_NOT_FOUND | 404 | Message with specified ID not found |
PROJECT_NOT_FOUND | 404 | Project does not exist |
PARENT_DIALOGUE_NOT_FOUND | 404 | Parent dialogue for thread not found |
RESOURCE_NOT_FOUND | 404 | Generic resource not found |
Conflict Errors (409)
| Code | HTTP Status | Description |
|---|---|---|
DIALOGUE_IMMUTABLE | 409 | Operation not allowed on immutable dialogue |
DUPLICATE_ID | 409 | Resource with this ID already exists |
RESOURCE_CONFLICT | 409 | Operation conflicts with resource state |
Rate Limit & Plan Limit Errors (429)
| Code | HTTP Status | Description |
|---|---|---|
RATE_LIMIT_EXCEEDED | 429 | Too many requests - retry after delay |
PLAN_LIMIT_EXCEEDED | 429 | Plan quota exceeded - upgrade to continue writing. Existing data remains accessible; only new writes are blocked. No overage charges. |
Server Errors (500)
| Code | HTTP Status | Description |
|---|---|---|
INTERNAL_ERROR | 500 | Unexpected server error |
DATABASE_ERROR | 500 | Database operation failed |
TRANSACTION_FAILED | 500 | Database transaction failed |
Error Handling Best Practices
1. Always Check HTTP Status Codes
typescript
const response = await fetch(url, options);
if (!response.ok) {
const error = await response.json();
switch (response.status) {
case 400:
// Validation error - fix request
console.error('Invalid request:', error.error.message);
break;
case 404:
// Not found - handle missing resource
console.error('Resource not found:', error.error.code);
break;
case 429:
// Rate limited - retry with backoff
await sleep(parseInt(response.headers.get('Retry-After')) * 1000);
return retry();
case 500:
// Server error - retry or alert
console.error('Server error:', error.error.requestId);
break;
}
}2. Use Error Codes for Logic
typescript
try {
const dialogue = await db.getDialogue(dialogueId);
} catch (error) {
if (error.code === 'DIALOGUE_NOT_FOUND') {
// Create new dialogue
return db.createDialogue({ ... });
}
if (error.code === 'RATE_LIMIT_EXCEEDED') {
// Wait and retry
await sleep(1000);
return retry();
}
// Unknown error - propagate
throw error;
}3. Handle Validation Errors with Details
typescript
try {
await dialogue.saveMessage(message);
} catch (error) {
if (error.type === 'validation_error' && error.details) {
// Show field-level errors to user
error.details.forEach(detail => {
console.error(`${detail.field}: ${detail.message}`);
});
}
}4. Log Request IDs for Support
typescript
try {
await api.dialogue.remove({ id: dialogueId });
} catch (error) {
// Always log requestId for debugging
console.error('Operation failed', {
requestId: error.requestId,
code: error.code,
message: error.message
});
// Show friendly message to user, provide requestId for support
alert(`Operation failed. Please contact support with ID: ${error.requestId}`);
}5. Implement Retry Logic for Transient Errors
typescript
async function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3
): Promise<T> {
let lastError;
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
lastError = error;
// Only retry on rate limits and server errors
if (error.code === 'RATE_LIMIT_EXCEEDED' || error.type === 'server') {
const delay = Math.min(1000 * Math.pow(2, i), 10000);
await sleep(delay);
continue;
}
// Don't retry validation or not found errors
throw error;
}
}
throw lastError;
}
// Usage
const dialogue = await withRetry(() => db.getDialogue(id));6. Handle Immutability Gracefully
typescript
try {
await dialogue.deleteMessage(messageId);
} catch (error) {
if (error.code === 'DIALOGUE_IMMUTABLE') {
console.error('Cannot modify messages in immutable dialogues');
console.log('Consider creating a new dialogue with corrected messages');
}
}SDK Error Handling
When using the official SDK, errors are automatically parsed:
typescript
import { DialogueDB, DialogueDBError } from 'dialogue-db';
const db = new DialogueDB({ apiKey: 'DIALOGUE_DB_API_KEY' });
try {
await db.getDialogue('invalid_id');
} catch (error) {
if (error instanceof DialogueDBError) {
console.log(error.code); // 'DIALOGUE_NOT_FOUND'
console.log(error.type); // 'not_found'
console.log(error.statusCode); // 404
console.log(error.requestId); // 'req_xyz'
console.log(error.message); // Human-readable message
}
}Testing Error Scenarios
Trigger Validation Errors
bash
# Missing required field
curl -X POST https://api.dialoguedb.com/dialogue \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
# Response: 400 with MISSING_PARAMETERTrigger Not Found Errors
bash
# Non-existent dialogue
curl -X GET https://api.dialoguedb.com/dialogue/invalid_id \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"
# Response: 404 with DIALOGUE_NOT_FOUNDTrigger Rate Limit Errors
bash
# Exceed rate limits
for i in {1..100}; do
curl -X GET https://api.dialoguedb.com/dialogue \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"
done
# Response: 429 with RATE_LIMIT_EXCEEDEDDebugging Tips
1. Use Request IDs
Every error includes a requestId. Provide this when contacting support:
Support Request:
- Request ID: req_abc123xyz
- Error Code: INTERNAL_ERROR
- Timestamp: 2025-11-06T21:34:21Z2. Enable Debug Logging
typescript
const client = new DialogueDB({
apiKey: 'DIALOGUE_DB_API_KEY',
debug: true // Log all requests and responses
});3. Check Response Headers
Rate limit information is in headers:
typescript
const response = await fetch(url, options);
console.log('Rate Limit:', response.headers.get('X-RateLimit-Limit'));
console.log('Remaining:', response.headers.get('X-RateLimit-Remaining'));
console.log('Reset:', response.headers.get('X-RateLimit-Reset'));Common Errors & Solutions
| Error | Cause | Solution |
|---|---|---|
DIALOGUE_NOT_FOUND | Dialogue doesn't exist or belongs to different project | Verify dialogue ID and project access |
MESSAGE_CONTENT_EMPTY | Empty message content | Ensure content field is not empty |
TOO_MANY_MESSAGES | More than 50 messages on creation | Split into multiple requests |
DIALOGUE_IMMUTABLE | Project has immutability enabled | Check project settings or create new dialogue |
RATE_LIMIT_EXCEEDED | Too many requests | Implement exponential backoff |
PLAN_LIMIT_EXCEEDED | Plan quota exceeded | Upgrade plan — reads still work, only writes blocked |
PROJECT_NOT_FOUND | Invalid project ID | Verify project exists and is accessible |
Support
If you encounter unexpected errors:
- Check the error code against this reference
- Note the
requestIdfrom the error response - Contact support with the request ID and error details
- Include relevant code that triggered the error
For real-time support:
- Email: support@dialoguedb.com
- Discord: Join our community
- Docs: https://docs.dialoguedb.com

