Error Code Catalog
Complete reference for all ObjectStack error codes with causes, fixes, and retry strategies
Error Code Catalog
ObjectStack uses a structured error system with 9 error categories and 41+ standardized error codes. Every error includes a machine-readable code, HTTP status mapping, and retry guidance.
Source: packages/spec/src/api/errors.zod.ts
Import: import { StandardErrorCodeSchema, ErrorCategorySchema, ErrorResponseSchema } from '@objectstack/spec/api'
Error Categories
| Category | HTTP Status | Description |
|---|---|---|
validation | 400 | Request data failed validation |
authentication | 401 | Identity not verified |
authorization | 403 | Insufficient permissions |
not_found | 404 | Resource does not exist |
conflict | 409 | State conflict or duplicate |
rate_limit | 429 | Too many requests |
server | 500 | Internal server error |
external | 502 | External service failure |
maintenance | 503 | System under maintenance |
Retry Strategies
| Strategy | Description | When to Use |
|---|---|---|
no_retry | Do not retry the request | Validation errors, permission denied |
retry_immediate | Retry immediately | Transient network errors |
retry_backoff | Retry with exponential backoff | Rate limits, server errors |
retry_after | Wait the specified retryAfter seconds | Rate limit with explicit cooldown |
Validation Errors (400)
validation_error
Cause: Generic validation failure — request body does not match expected schema.
Fix: Check the fieldErrors array for specific field-level issues.
Retry: no_retry
{
"code": "validation_error",
"message": "Request validation failed",
"category": "validation",
"httpStatus": 400,
"retryable": false,
"fieldErrors": [
{ "field": "email", "message": "Invalid email format", "code": "invalid_format" }
]
}invalid_field
Cause: A field name in the request does not exist on the target object.
Fix: Check the object schema for valid field names. Use objectstack explain <object> to see available fields.
Retry: no_retry
missing_required_field
Cause: A required field was not provided in the request body.
Fix: Include the missing field. Check fieldErrors for the field name.
Retry: no_retry
invalid_format
Cause: Field value does not match the expected format (e.g., invalid email, wrong date format).
Fix: Ensure the value matches the field's format constraint or built-in type validation.
Retry: no_retry
value_too_long
Cause: String value exceeds the field's maxLength constraint.
Fix: Truncate the value to the maximum allowed length.
Retry: no_retry
value_too_short
Cause: String value is below the field's minLength constraint.
Fix: Provide a longer value that meets the minimum length requirement.
Retry: no_retry
value_out_of_range
Cause: Numeric value is outside the field's min/max range.
Fix: Ensure the value is within the allowed range.
Retry: no_retry
invalid_reference
Cause: A lookup or master_detail field references a record that does not exist.
Fix: Verify the referenced record ID exists in the target object.
Retry: no_retry
duplicate_value
Cause: A field with unique: true already has a record with the same value.
Fix: Use a different value or update the existing record.
Retry: no_retry
invalid_query
Cause: The query structure is malformed.
Fix: Check the query syntax against the Query Cheat Sheet.
Retry: no_retry
invalid_filter
Cause: A filter operator or field in the where clause is invalid.
Fix: Use valid filter operators ($eq, $ne, $gt, $lt, $in, $contains, etc.).
Retry: no_retry
invalid_sort
Cause: The orderBy clause references a non-existent or non-sortable field.
Fix: Ensure the field exists and has sortable: true.
Retry: no_retry
max_records_exceeded
Cause: The request attempts to create or return more records than the system limit.
Fix: Use pagination (limit/offset or cursor-based) for large datasets. Batch operations for bulk creates.
Retry: no_retry
Authentication Errors (401)
unauthenticated
Cause: No authentication credentials were provided.
Fix: Include a valid Authorization header (Bearer token, API key, or session cookie).
Retry: no_retry
invalid_credentials
Cause: Username/password combination is incorrect.
Fix: Verify credentials and try again. After multiple failures, account may be locked.
Retry: no_retry
expired_token
Cause: The authentication token (JWT, session token) has expired.
Fix: Obtain a new token using the refresh token endpoint or re-authenticate.
Retry: retry_immediate (after refreshing token)
invalid_token
Cause: The authentication token is malformed or has been tampered with.
Fix: Obtain a fresh token from the authentication endpoint.
Retry: no_retry
session_expired
Cause: The user session has timed out due to inactivity.
Fix: Re-authenticate to start a new session.
Retry: no_retry
mfa_required
Cause: Multi-factor authentication is required but the MFA challenge has not been completed.
Fix: Complete the MFA verification step before proceeding.
Retry: no_retry
email_not_verified
Cause: The user's email address has not been verified.
Fix: Complete email verification through the link sent to the user's email.
Retry: no_retry
Authorization Errors (403)
permission_denied
Cause: The authenticated user does not have permission for this operation.
Fix: Request the necessary permissions from an administrator, or use an account with the required role.
Retry: no_retry
insufficient_privileges
Cause: The user has some access but lacks the specific privilege required for this action.
Fix: Contact an administrator to grant the necessary privilege.
Retry: no_retry
field_not_accessible
Cause: The user does not have access to a specific field on the object.
Fix: Remove the inaccessible field from the request, or request field-level access.
Retry: no_retry
record_not_accessible
Cause: The user cannot access this specific record due to record-level sharing rules.
Fix: Request access to the record from its owner or an administrator.
Retry: no_retry
license_required
Cause: The feature requires a specific license that is not active.
Fix: Upgrade the license or contact your administrator.
Retry: no_retry
ip_restricted
Cause: The request originates from an IP address that is not in the allowlist.
Fix: Ensure the request comes from an approved IP range, or update the IP restriction settings.
Retry: no_retry
time_restricted
Cause: Access is limited to specific time windows and the current time is outside the allowed range.
Fix: Retry during the allowed time window.
Retry: retry_after
Not Found Errors (404)
resource_not_found
Cause: The requested resource does not exist (generic).
Fix: Verify the resource identifier and endpoint path.
Retry: no_retry
object_not_found
Cause: The specified object (table/entity) does not exist in the schema.
Fix: Check the object name. Use objectstack explain to list available objects.
Retry: no_retry
record_not_found
Cause: No record exists with the given ID in the specified object.
Fix: Verify the record ID. The record may have been deleted.
Retry: no_retry
field_not_found
Cause: The specified field does not exist on the object.
Fix: Check the field name against the object schema. Field names are snake_case.
Retry: no_retry
endpoint_not_found
Cause: The API endpoint path does not match any registered route.
Fix: Verify the URL path and HTTP method. Check the API discovery endpoint for available routes.
Retry: no_retry
Conflict Errors (409)
resource_conflict
Cause: The operation conflicts with the current state of the resource.
Fix: Fetch the latest resource state and retry the operation.
Retry: retry_immediate
concurrent_modification
Cause: The record was modified by another user/process since you last read it (optimistic locking failure).
Fix: Re-fetch the record, merge changes, and retry.
Retry: retry_immediate
delete_restricted
Cause: The record cannot be deleted because other records depend on it (referential integrity).
Fix: Delete or reassign dependent records first, then retry the delete.
Retry: no_retry
duplicate_record
Cause: A record with the same unique key already exists.
Fix: Update the existing record instead, or use a different unique key value.
Retry: no_retry
lock_conflict
Cause: The record is locked by another process or user.
Fix: Wait for the lock to be released, or contact the lock holder.
Retry: retry_backoff
Rate Limit Errors (429)
rate_limit_exceeded
Cause: Too many requests in the current time window.
Fix: Reduce request frequency. Check the retryAfter field for the wait time.
Retry: retry_after
quota_exceeded
Cause: The API usage quota for the current period has been exhausted.
Fix: Wait for the quota to reset (check retryAfter), or upgrade the plan.
Retry: retry_after
concurrent_limit_exceeded
Cause: Too many concurrent requests from the same client.
Fix: Reduce parallel request count. Implement request queuing.
Retry: retry_backoff
Server Errors (500)
internal_error
Cause: An unexpected server-side error occurred.
Fix: Report the issue with the requestId and traceId. Retry may succeed.
Retry: retry_backoff
database_error
Cause: A database operation failed (connection, query, constraint).
Fix: Report the issue. May be transient — retry with backoff.
Retry: retry_backoff
timeout
Cause: The operation exceeded the maximum allowed time.
Fix: Simplify the query/operation. For large datasets, use pagination or async processing.
Retry: retry_backoff
service_unavailable
Cause: A required internal service is temporarily unavailable.
Fix: Retry after a brief delay. Check system status.
Retry: retry_backoff
not_implemented
Cause: The requested feature or endpoint is not yet implemented.
Fix: Check the documentation for alternative approaches, or wait for the feature release.
Retry: no_retry
External Service Errors (502)
external_service_error
Cause: An external API or service returned an error.
Fix: Check the external service status. The details field may contain the upstream error.
Retry: retry_backoff
integration_error
Cause: An integration connector encountered an error.
Fix: Verify the integration configuration and credentials.
Retry: retry_backoff
webhook_delivery_failed
Cause: A webhook delivery attempt failed (target unreachable or returned error).
Fix: Verify the webhook URL is accessible. The system will auto-retry per delivery policy.
Retry: retry_backoff
Batch Operation Errors
batch_partial_failure
Cause: Some operations in a batch request succeeded while others failed.
Fix: Check the details for individual operation results. Retry only the failed operations.
Retry: retry_immediate (failed operations only)
batch_complete_failure
Cause: All operations in the batch request failed.
Fix: Check the details for root cause. Fix and retry the entire batch.
Retry: retry_backoff
transaction_failed
Cause: A database transaction failed and was rolled back.
Fix: Check the details for the specific failure. Retry the entire transaction.
Retry: retry_backoff
Error Response Structure
Every error response follows the EnhancedApiError schema:
interface EnhancedApiError {
code: StandardErrorCode; // Machine-readable error code
message: string; // Human-readable description
category?: ErrorCategory; // Error category
httpStatus?: number; // HTTP status code
retryable: boolean; // Whether retry may succeed
retryStrategy?: RetryStrategy; // Recommended retry approach
retryAfter?: number; // Seconds to wait (for rate limits)
details?: unknown; // Additional error context
fieldErrors?: FieldError[]; // Field-specific validation errors
timestamp?: string; // ISO 8601 timestamp
requestId?: string; // Request tracking ID
traceId?: string; // Distributed trace ID
documentation?: string; // URL to error documentation
helpText?: string; // Suggested resolution actions
}Field Error Structure
interface FieldError {
field: string; // Field name that has the error
message: string; // Human-readable error for this field
code?: string; // Field-level error code
value?: unknown; // The invalid value (if safe to include)
}Client-Side Error Handling
TypeScript Example
import type { EnhancedApiError } from '@objectstack/spec/api';
async function handleApiCall() {
try {
const result = await client.records.create('task', { title: 'New Task' });
return result;
} catch (error) {
const apiError = error as EnhancedApiError;
switch (apiError.category) {
case 'validation':
// Show field-level errors to the user
apiError.fieldErrors?.forEach(fe => {
showFieldError(fe.field, fe.message);
});
break;
case 'authentication':
// Redirect to login
if (apiError.code === 'expired_token') {
await refreshToken();
return handleApiCall(); // Retry
}
redirectToLogin();
break;
case 'rate_limit':
// Wait and retry
const waitTime = apiError.retryAfter ?? 60;
await sleep(waitTime * 1000);
return handleApiCall();
case 'server':
case 'external':
// Log and retry with backoff
console.error(`Server error [${apiError.requestId}]:`, apiError.message);
break;
default:
showGenericError(apiError.message);
}
}
}HTTP Status Quick Reference
| Status | Category | Common Codes |
|---|---|---|
| 400 | validation | validation_error, invalid_field, missing_required_field, invalid_query |
| 401 | authentication | unauthenticated, expired_token, invalid_credentials |
| 403 | authorization | permission_denied, field_not_accessible, license_required |
| 404 | not_found | record_not_found, object_not_found, endpoint_not_found |
| 409 | conflict | concurrent_modification, duplicate_record, delete_restricted |
| 429 | rate_limit | rate_limit_exceeded, quota_exceeded |
| 500 | server | internal_error, database_error, timeout |
| 502 | external | external_service_error, integration_error |
| 503 | maintenance | service_unavailable |