Errors
Errors protocol schemas
Standardized Error Codes Protocol
Implements P0 requirement for ObjectStack kernel. Provides consistent, machine-readable error codes across the platform.
Features:
- Categorized error codes (validation, authentication, authorization, etc.)
- HTTP status code mapping
- Localization support
- Retry guidance
Industry alignment: Google Cloud Errors, AWS Error Codes, Stripe API Errors
Source: packages/spec/src/api/errors.zod.ts
TypeScript Usage
import { EnhancedApiErrorSchema, ErrorCategory, ErrorResponseSchema, FieldErrorSchema, FieldErrorCode, RetryStrategy, StandardErrorCode } from '@objectstack/spec/api';
import type { EnhancedApiError, ErrorCategory, ErrorResponse, FieldError, FieldErrorCode, RetryStrategy, StandardErrorCode } from '@objectstack/spec/api';
// Validate data
const result = EnhancedApiErrorSchema.parse(data);EnhancedApiError
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| code | Enum<'VALIDATION_ERROR' | 'INVALID_FIELD' | 'MISSING_REQUIRED_FIELD' | 'INVALID_FORMAT' | 'VALUE_TOO_LONG' | 'VALUE_TOO_SHORT' | 'VALUE_OUT_OF_RANGE' | … +46 more> | ✅ | Machine-readable error code |
| message | string | ✅ | Human-readable error message |
| category | Enum<'validation' | 'authentication' | 'authorization' | 'not_found' | 'conflict' | 'rate_limit' | 'server' | 'external' | 'maintenance'> | optional | Error category |
| httpStatus | number | optional | HTTP status code |
| retryable | boolean | ✅ | Whether the request can be retried |
| retryStrategy | Enum<'no_retry' | 'retry_immediate' | 'retry_backoff' | 'retry_after'> | optional | Recommended retry strategy |
| retryAfter | number | optional | Seconds to wait before retrying |
| details | any | optional | Additional error context |
| fields | { field: string; code: Enum<'required' | 'invalid_type' | 'invalid_shape' | 'unknown_field' | … +24 more>; message: string; label?: string; … }[] | optional | One entry per offending value |
| fieldErrors | never | optional | [REMOVED] EnhancedApiError.fieldErrors was renamed to fields in @objectstack/spec 17 (ADR-0114 D4, #3977) — the array is unchanged, only the property name. Every producer already emitted fields; fieldErrors was declared and never emitted, so a reader keying on it was reading a field no server sent. |
| timestamp | string | optional | When the error occurred |
| requestId | string | optional | Request ID for tracking |
| traceId | string | optional | Distributed trace ID |
| documentation | string | optional | URL to error documentation |
| helpText | string | optional | Suggested actions to resolve the error |
Allowed Values: EnhancedApiError.code
VALIDATION_ERRORINVALID_FIELDMISSING_REQUIRED_FIELDINVALID_FORMATVALUE_TOO_LONGVALUE_TOO_SHORTVALUE_OUT_OF_RANGEINVALID_REFERENCEDUPLICATE_VALUEINVALID_QUERYINVALID_FILTERINVALID_SORTMAX_RECORDS_EXCEEDEDUNAUTHENTICATEDINVALID_CREDENTIALSEXPIRED_TOKENINVALID_TOKENSESSION_EXPIREDMFA_REQUIREDEMAIL_NOT_VERIFIEDPERMISSION_DENIEDINSUFFICIENT_PRIVILEGESFIELD_NOT_ACCESSIBLERECORD_NOT_ACCESSIBLELICENSE_REQUIREDIP_RESTRICTEDTIME_RESTRICTEDRESOURCE_NOT_FOUNDOBJECT_NOT_FOUNDRECORD_NOT_FOUNDFIELD_NOT_FOUNDENDPOINT_NOT_FOUNDRESOURCE_CONFLICTCONCURRENT_MODIFICATIONDELETE_RESTRICTEDDUPLICATE_RECORDLOCK_CONFLICTMETHOD_NOT_ALLOWEDPRECONDITION_REQUIREDRATE_LIMIT_EXCEEDEDQUOTA_EXCEEDEDCONCURRENT_LIMIT_EXCEEDEDINTERNAL_ERRORDATABASE_ERRORTIMEOUTSERVICE_UNAVAILABLENOT_IMPLEMENTEDEXTERNAL_SERVICE_ERRORINTEGRATION_ERRORWEBHOOK_DELIVERY_FAILEDBATCH_PARTIAL_FAILUREBATCH_COMPLETE_FAILURETRANSACTION_FAILED
ErrorCategory
Allowed Values
validationauthenticationauthorizationnot_foundconflictrate_limitserverexternalmaintenance
ErrorResponse
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| success | false | ✅ | Always false for error responses |
| error | { code: Enum<'VALIDATION_ERROR' | 'INVALID_FIELD' | 'MISSING_REQUIRED_FIELD' | … +50 more>; message: string; category?: Enum<'validation' | 'authentication' | 'authorization' | 'not_found' | 'conflict' | … +4 more>; httpStatus?: number; … } | ✅ | Error details |
| meta | { timestamp?: string; requestId?: string; traceId?: string } | optional | Response metadata |
FieldError
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| field | string | ✅ | Field path (supports dot notation) |
| code | Enum<'required' | 'invalid_type' | 'invalid_shape' | 'unknown_field' | 'invalid_boolean' | 'invalid_number' | 'invalid_date' | 'invalid_time' | 'invalid_email' | … +19 more> | ✅ | Which constraint the value violated (field-level catalog, ADR-0114) |
| message | string | ✅ | Human-readable error message, rendered in the caller’s locale |
| label | string | optional | Field display label in the caller’s locale |
| value | any | optional | The invalid value that was provided |
| constraint | Record<string, any> | optional | The constraint that was violated, as discrete values (e.g. { maxLength: 512, actual: 3000 }) |
Allowed Values: FieldError.code
requiredinvalid_typeinvalid_shapeunknown_fieldinvalid_booleaninvalid_numberinvalid_dateinvalid_timeinvalid_emailinvalid_urlinvalid_phoneinvalid_jsoninvalid_formatmin_lengthmax_lengthmin_valuemax_valuemax_scalemin_itemsmax_itemsinvalid_optioninvalid_valuereference_not_foundreference_ambiguousrule_violationjson_schema_violationinvalid_initial_stateinvalid_transition
FieldErrorCode
Allowed Values
requiredinvalid_typeinvalid_shapeunknown_fieldinvalid_booleaninvalid_numberinvalid_dateinvalid_timeinvalid_emailinvalid_urlinvalid_phoneinvalid_jsoninvalid_formatmin_lengthmax_lengthmin_valuemax_valuemax_scalemin_itemsmax_itemsinvalid_optioninvalid_valuereference_not_foundreference_ambiguousrule_violationjson_schema_violationinvalid_initial_stateinvalid_transition
RetryStrategy
Allowed Values
no_retryretry_immediateretry_backoffretry_after
StandardErrorCode
Allowed Values
VALIDATION_ERRORINVALID_FIELDMISSING_REQUIRED_FIELDINVALID_FORMATVALUE_TOO_LONGVALUE_TOO_SHORTVALUE_OUT_OF_RANGEINVALID_REFERENCEDUPLICATE_VALUEINVALID_QUERYINVALID_FILTERINVALID_SORTMAX_RECORDS_EXCEEDEDUNAUTHENTICATEDINVALID_CREDENTIALSEXPIRED_TOKENINVALID_TOKENSESSION_EXPIREDMFA_REQUIREDEMAIL_NOT_VERIFIEDPERMISSION_DENIEDINSUFFICIENT_PRIVILEGESFIELD_NOT_ACCESSIBLERECORD_NOT_ACCESSIBLELICENSE_REQUIREDIP_RESTRICTEDTIME_RESTRICTEDRESOURCE_NOT_FOUNDOBJECT_NOT_FOUNDRECORD_NOT_FOUNDFIELD_NOT_FOUNDENDPOINT_NOT_FOUNDRESOURCE_CONFLICTCONCURRENT_MODIFICATIONDELETE_RESTRICTEDDUPLICATE_RECORDLOCK_CONFLICTMETHOD_NOT_ALLOWEDPRECONDITION_REQUIREDRATE_LIMIT_EXCEEDEDQUOTA_EXCEEDEDCONCURRENT_LIMIT_EXCEEDEDINTERNAL_ERRORDATABASE_ERRORTIMEOUTSERVICE_UNAVAILABLENOT_IMPLEMENTEDEXTERNAL_SERVICE_ERRORINTEGRATION_ERRORWEBHOOK_DELIVERY_FAILEDBATCH_PARTIAL_FAILUREBATCH_COMPLETE_FAILURETRANSACTION_FAILED