Error Code Ledger — API Protocol reference
Error-Code Ledger. Reference for ErrorCode, ProvenanceWaiver, StandardSynonymWaiver: every property with its type and default.
Error-Code Ledger (ADR-0112 D3).
The top-level error.code vocabulary is two-tier:
- Standard catalog —
StandardErrorCode(errors.zod.ts): a small, closed set with platform-wide HTTP semantics. It does NOT grow when a service invents a code. - Registered extension codes — THIS ledger: every service-specific code
a route may put in
error.code, registered under its owning package.
ErrorCode (exported below) is the union, and is what ApiErrorSchema.code
validates against. An unregistered code fails schema parse — which fails the
envelope conformance suites — which fails CI. That friction is the point
(ADR-0112: "no silent fourth state" for error codes, per ADR-0049/0078).
Scope: THIS ledger registers framework packages only (#4805)
Every owner key below is a package published from this repository, and that
is a RULE — not an accident of the current list, and not something a reader
should have to infer by scanning the package names. A downstream product
repo (objectstack-ai/cloud, or any product built on the platform) does
not register its codes here. It maintains its OWN ledger, in its own
repo, and composes the validation itself:
- shape —
envelopeViolations(body)(contract.zod.ts), and - vocabulary —
code ∈ StandardErrorCode ∪ <its own ledger>, whichmakeApiErrorSchema(<its own ledger>)(contract.zod.ts) gives as a single parse instead of the two-step assertion.
The deployed wire vocabulary stays closed and checkable either way — which is what ADR-0112's "no silent fourth state" asks for. It never asked for every entry to live physically in one file.
Why federated rather than admitting downstream entries (maintainer ruling on #4805, 2026-08-03, re-confirmed 2026-08-09; raised from cloud#930/#944):
- A commercial vocabulary does not belong in an Apache-2.0 spec. The codes worth registering are precisely the product-specific ones (billing and plan-gating states, control-plane provisioning refusals), and registering them here would have the OSS spec enumerate a closed-source product's states under package names absent from this distribution.
- Cadence mismatch breeds bypass. A downstream code arrives with a downstream feature; making each one cost a cross-repo PR plus a pin bump pushes authors toward reusing a semantically wrong existing code, which is less visible than inventing one.
The corollary for THIS file: a PR adding an owner key for a package that is not published from this repository is out of scope by construction — the fix for that need is a ledger in the owning repo, composed as above. The one thing a downstream repo must NOT do is emit a code registered nowhere: that is the silent fourth state, wherever the ledger lives.
Registering a new code
Add it to your package's entry (create the entry if your package has none —
a framework package; see the scope rule above if yours ships from another
repo), SCREAMING_SNAKE (^[A-Z][A-Z0-9_]*$ — lint-enforced by
error-code-ledger.test.ts), with a trailing // comment when the name
alone doesn't carry the meaning. Prefer a domain prefix for anything not
self-evidently global (ATTACHMENT_*, APPROVAL_*, SETTINGS_*). If the
condition is generic (not found / permission / validation / rate limit),
use the standard catalog instead of registering a synonym.
Since #8211 (adjudicated 2026-08-12, option C) that last sentence is
MECHANICAL, not prose: the admission gate (error-code-ledger.test.ts)
refuses a new code that standardSynonymOf maps to a standard-catalog
member, unless the code carries a STANDARD_SYNONYM_WAIVERS entry
recording why it stays and which member it shadows. Four synonyms had
accumulated by the time the rule got teeth precisely because nothing was
checking; they (plus a fifth the detector surfaced on landing) are
grandfathered via waivers below — their wire values are unchanged, and
consolidating any of them onto its standard member is a deliberate wire
change DEFERRED by the #8211 adjudication (option B) until a specific code
has a measured victim.
One rule, two doors (#8087, completed by #9106): registration here is the
ADMISSION door — what the vocabulary may contain. The DISPATCHER door is
gated (#8087, option B-as-a-gate, maintainer 2026-08-12:
check:dispatcher-error-vocabulary sweeps its producers) and, since the
#9106 ruling (maintainer 2026-08-16), NARROWS exactly as the REST door
always has: resolveThrownHttpError (@objectstack/types) answers code
(a member of this union) for error.code at BOTH doors, and a producer's
unregistered spelling is demoted to the wire's declaredCode — the open,
author-authored channel ApiErrorSchema declares for it. Both doors state
the same rule: a code either IS the standard member for its condition, or it
is registered here — and if it merely re-spells a standard member, that
registration is a recorded waiver, never drift. A code registered NOWHERE
(a tenant app's own spelling) still reaches the wire, in declaredCode.
Door or no door — every code that ships in dist is registered (#16404)
Ruled by the director seat (decision batch #62, 2026-09-07, option D;
maintainer 「同意」): the published contract face for error codes is THIS
ledger together with StandardErrorCode. Any code that ships in a
package's dist is registered here whether or not an HTTP door can ever
answer with it — a thrown value's code is what a consumer's
catch (e) { switch (e.code) } pins, and once shipped it cannot be renamed
without breaking that consumer. Registering a code widens this face and is
therefore a Clause-② change, door or no door; a code present in dist and
absent here is a protocol gap, not a tier question.
ONE shape, no second list: a door: 'none' code is a row like any other —
the string under the package that stamps it, and a comment that states its
status and the reachability reading ("no HTTP door on this tree; the
thrown value is the boundary"). Until commit 44c917a47 the dispatcher vocabulary
(packages/runtime/src/dispatcher-error-vocabulary.ts) carried a
boot-refusal verdict that recorded that same reachability for the codes
NOT yet registered; it is RETIRED, because the gate below now refuses it —
and every verdict like it — under any published package's src/. The one
verdict that still parks a site there is pending-registration, and only
outside packages/spec/src/**, under the dated allowance spelled out below.
So a door: 'none' code has no resting place short of a row here, and the
ratchet is the one pending-registration already had: a row here makes the
site vanish from that scan. What registration changes
for such a code is the face,
not the wire: nothing demotes today, and if a door ever does answer with
it, error.code carries the specific code instead of the status-derived
member plus declaredCode. The declaredCode demotion (#9106) stays for
genuinely unknown / third-party spellings only.
EVERY published package's src/** is held to this mechanically — commit 44c917a47
widened the rule from packages/spec/src/** alone, which is all #16449
could afford to measure. check:dispatcher-error-vocabulary refuses to
classify a stamp site under one as anything but foreign-vocabulary (a
different vocabulary that merely spells itself code) or runtime-pinned,
and the only way out is the row here. Under packages/spec/src/** that is
the whole rule, so a pending-registration row for a spec site is a finding
(spec-face-unregistered); outside it, a pending-registration row keeps a
named, dated allowance owed to #8846 and any OTHER verdict is a finding
(published-face-unregistered).
A code emitted by several packages is listed once per emitting package — the union dedupes; the per-package rows are provenance, not identity.
Since #13353 that sentence has a mechanical half: the provenance gate
(check:error-code-provenance, packages/spec/scripts/) sweeps every
stamp site of a REGISTERED code in packages/** non-test source and fails
when the stamping package's own owner key does not list it. The admission
rules below never ask WHO emits, so before that gate an unlisted emitter was
invisible to every gate the repo has (three hand sweeps found the same class
three times: #7504, #13254, #13353). Two deliberate shapes are NOT rows and
are recorded in PROVENANCE_WAIVERS instead: a DOOR in another
package that names the wire vocabulary itself (FLOW_DISABLED,
UPDATE_ID_MISMATCH — see their rows' comments), and a shared constructor
package whose throw is served under another package's registration.
Retiring a code
A row whose last EMITTER is deleted comes out with it. The admission rules
below check casing, duplication and shadowing — never whether anyone still
throws the code — so a registered-but-unemittable row stays green forever
while promising a client a code no response can carry. That is ADR-0112's
"no silent fourth state" read backwards, and it is not hypothetical:
OVERLAY_PERSISTENCE_FAILED outlived its only producer by one PR (#5264
deleted saveMetaItem's legacy raw-engine branch; #5783 unregistered the
code). Nor does a row need to LOSE its producer to be in this class — a
throw site whose error can never reach a response envelope was unemittable
from birth: MONGODB_MULTI_TENANT_UNSUPPORTED (registered by #3724,
unregistered by #8035) is a BOOT refusal — the CLI rethrows it pre-HTTP and
aborts, and the one request-reachable trigger sits inside a documented
best-effort catch that logs and continues. Its throw site and constant
(MULTI_TENANT_UNSUPPORTED_CODE, @objectstack/driver-mongodb) live on:
host boot matching is not wire vocabulary.
⚠️ That SECOND ground is superseded by #16404 ("Door or no door" above): a
boot refusal that ships in dist is owed a row, so the codes left out or
retired on the "not wire vocabulary" reasoning were registrations owed
under the ruling, not re-argued per card — #16449 registered the nine
measured on its tree, and commit 613bfbd3d the fourteen boot-refusal rows
dispatcher-error-vocabulary.ts still carried, among them
MONGODB_MULTI_TENANT_UNSUPPORTED itself, back under
@objectstack/driver-mongodb with the #8035 removal reversed on the
record. What still retires a row is the FIRST ground only: no producer
left anywhere in packages/** source.
Before deleting a row, check that no producer remains repo-wide AND
that no consumer — including objectui and cloud — reads the literal;
tests that merely CONSTRUCT the code are not producers, and a test pinned to
a producerless code is pinning nothing (#4984's phantom-check family).
Field-level codes (FieldErrorSchema.code, the fields[] array) are a
SEPARATE vocabulary and do not belong here — see #3977 (ADR-0112 D6).
Source: packages/spec/src/api/error-code-ledger.zod.ts
TypeScript Usage
import { ErrorCode, ProvenanceWaiverSchema, StandardSynonymWaiverSchema } from '@objectstack/spec/api';
import type { ErrorCode, ProvenanceWaiver, StandardSynonymWaiver } from '@objectstack/spec/api';
// Validate data
const result = ErrorCode.parse(data);ErrorCode
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_EXCEEDEDINTERNAL_ERRORDATABASE_ERRORTIMEOUTSERVICE_UNAVAILABLENOT_IMPLEMENTEDEXTERNAL_SERVICE_ERRORINTEGRATION_ERRORWEBHOOK_DELIVERY_FAILEDACCOUNT_LOCKEDACTION_CONFIRMATION_REQUIREDACTION_DISABLEDALREADY_REVERTEDAMBIGUOUS_MATCHANALYTICS_DATE_RANGE_UNRECOGNIZEDANALYTICS_QUERY_FAILEDAPPROVAL_ACTIONS_FAILEDAPPROVAL_APPROVE_FAILEDAPPROVAL_COMMENT_FAILEDAPPROVAL_REASSIGN_FAILEDAPPROVAL_RECALL_FAILEDAPPROVAL_REJECT_FAILEDAPPROVAL_REMIND_FAILEDAPPROVAL_REQUEST_GET_FAILEDAPPROVAL_REQUEST_INFO_FAILEDAPPROVAL_REQUEST_LIST_FAILEDAPPROVAL_RESUBMIT_FAILEDAPPROVAL_REVISE_FAILEDASYNC_NOT_SUPPORTEDATTACHMENT_DELETE_DENIEDATTACHMENT_DOWNLOAD_DENIEDATTACHMENT_PARENT_ACCESSAUDIENCE_NOT_ALLOWEDAUDIT_TYPE_NOT_CANONICALAUTH_CONFIG_ERRORAUTH_REQUIREDAUTOMATION_UNSCOPED_RUN_DATA_ACCESSBATCH_ABORTEDBATCH_NOT_ATOMICBATCH_TOO_LARGEBATCH_UNRESOLVED_REFBLANK_MATCH_KEYCLONE_DISABLEDCLOUD_FETCH_FAILEDCLOUD_UNCONFIGUREDCOMMIT_NOT_FOUNDCONCURRENT_UPDATECONFLICTCONFLICTING_MAPPINGCONNECTOR_UPSTREAM_UNAVAILABLECREATE_FAILEDCUBE_NOT_FOUNDDATASET_INVALIDDATASOURCE_ADMIN_ERRORDELEGABLE_SCOPE_FAILEDDELETE_HOOK_RESULT_NOT_WRITE_SHAPEDELIVERY_NEVER_SENTDELIVERY_NOT_ELIGIBLEDESTRUCTIVE_CHANGEDEVICE_CODE_FAILEDDOMAIN_VERIFICATION_DISABLEDDOMAIN_VERIFICATION_FAILEDDRIVER_UNAVAILABLEDUPLICATE_ARTIFACT_OBJECT_NAMEDUPLICATE_ARTIFACT_PACKAGEDUPLICATE_REQUESTDUPLICATE_SOURCE_NOT_A_BASEELIGIBILITY_UNEVALUABLEEMAIL_DOMAIN_NOT_ALLOWEDEMAIL_SEND_FAILEDEMAIL_SERVICE_REQUIREDENQUEUE_FAILEDENVIRONMENT_BIND_FAILEDENVIRONMENT_NOT_FOUNDENV_ACCESS_DENIEDERR_AUTONUMBER_COLLISIONERR_BULK_RESULT_MISMATCHERR_CROSS_DATASOURCE_TRANSACTION_WRITEERR_DATASOURCE_UNAVAILABLEERR_DRIVER_CONNECTERR_FILE_CONSTRAINTERR_FILE_REFERENCE_COPYERR_HOOK_TARGET_REBINDERR_READONLY_FIELD_REJECTEDERR_SUMMARY_RECOMPUTEERR_SYSTEM_WRITE_ORGANIZATION_REQUIREDERR_TRANSACTION_UNSUPPORTEDEXECUTION_ERROREXPIRED_OR_REVOKEDEXPIRY_IN_PASTEXPIRY_TOO_LONGEXPLAIN_FAILEDEXPORT_NOT_PERMITTEDEXTERNAL_DATASOURCE_ERROREXTERNAL_IMPORT_ERROREXTERNAL_SCHEMA_MISMATCHEXTERNAL_SCHEMA_MODE_VIOLATIONEXTERNAL_WRITE_FORBIDDENFEEDS_DISABLEDFIELD_VISIBILITY_UNRESOLVEDFILES_DISABLEDFILE_DOWNLOAD_DENIEDFILE_FIELD_BULK_WRITE_REFUSEDFILE_NOT_FOUNDFILTER_TOKEN_UNKNOWNFILTER_TOKEN_UNRESOLVEDFIND_HOOK_RESULT_NOT_ARRAYFIND_ONE_HOOK_RESULT_NOT_RECORDFLOW_CONVERSION_CONFLICTFLOW_DISABLEDFLOW_FAILEDFLOW_INPUT_SCHEMA_INVALIDFLOW_NO_START_NODEFORBIDDENFORM_NOT_FOUNDFORM_RESOLVE_FAILEDHOOK_UNSCOPED_DATA_ACCESSIMPORT_JOB_CREATE_FAILEDIMPORT_ROW_FAILEDINTERNALINVALID_ARTIFACT_PACKAGESINVALID_ARTIFACT_PACKAGE_ENTRYINVALID_EMAILINVALID_EXPIRYINVALID_METADATAINVALID_OR_EXPIREDINVALID_PHONEINVALID_REQUESTINVALID_RESUME_TOKENINVALID_SCREEN_INPUTINVALID_SIGNALINVALID_SIGNATUREINVALID_STATEINVITE_EMAIL_FAILEDINVITE_REQUIRES_EMAILINVITE_SMS_FAILEDIP_NOT_ALLOWEDITEM_LOCKEDLAST_LOCAL_CREDENTIALMANIFEST_CONFLICTMAPPING_FORMAT_MISMATCHMAPPING_FORMAT_UNSUPPORTEDMAPPING_NOT_FOUNDMAPPING_TARGET_MISMATCHMARKETPLACE_PROXY_FAILEDMARKETPLACE_STORAGE_FAILEDMARKETPLACE_UNAVAILABLEMEMORY_MULTI_TENANT_UNSUPPORTEDMETADATA_BRANCHMETADATA_CONFLICTMETADATA_NOT_FOUNDMETADATA_SCHEMA_INVALIDMIXED_ARTIFACT_COLLECTION_SHAPEMONGODB_MULTI_TENANT_UNSUPPORTEDMULTI_UPDATE_HOOK_KEY_DIVERGENCENAMESPACE_CONFLICTNAMESPACE_PREFIXNEEDS_PASSWORDNODE_FAILURENOTHING_TO_PURGENOT_ATTEMPTEDNOT_COMPENSABLENOT_CREATABLENOT_FOUNDNOT_OVERRIDABLENOT_UNDOABLENO_DRAFTNO_EXECUTORNO_IDENTITYNO_MATCHNO_PENDING_VERIFICATIONNO_SUCH_RUNOAUTH_REGISTER_FAILEDOBJECT_API_DISABLEDOBJECT_API_METHOD_NOT_ALLOWEDOBJECT_OVERLAY_PACKAGE_MISMATCHOBJECT_OWNERSHIP_CONFLICTOBJECT_PACKAGE_DISABLEDOPENAPI_UNAVAILABLEOS_PROTOCOL_INCOMPATIBLEPACKAGE_DELETE_FAILEDPACKAGE_DELETE_PARTIALPACKAGE_MANIFEST_INVALIDPACKAGE_PUBLISH_FAILEDPASSWORD_ALREADY_SETPASSWORD_EXPIREDPASSWORD_POLICY_VIOLATIONPASSWORD_REUSEPAYLOAD_TOO_LARGEPERMISSION_NOT_ALLOWEDPHONE_NOT_ENABLEDPLAN_CHANGEDPLUGIN_CONTRACT_VIOLATIONPLUGIN_INSTALL_FAILEDPLUGIN_MANIFEST_INVALIDPLUGIN_REGISTER_FAILEDPLUGIN_UI_REQUIRED_KEY_MISSINGPREFLIGHT_FAILEDPROJECT_MEMBERSHIP_REQUIREDPROJECT_NOT_FOUNDPROJECT_PROVISIONINGPROJECT_PROVISIONING_FAILEDQUERY_OBJECT_MISMATCHRAW_SQL_UNSUPPORTEDREAD_BACK_FAILEDREAD_SCOPE_COMPILE_FAILEDRECORD_GONERECORD_LOCKEDRECORD_NOT_ELIGIBLEREGISTRY_TYPE_NOT_CANONICALREQUEST_NOT_FOUNDRESEED_NO_ROWSRESEED_SKIPPEDRESUME_FAILEDRESUME_IN_PROGRESSRESUME_TARGET_LOSTROLLED_BACKROUTE_NOT_FOUNDRULE_DEFINE_FAILEDRULE_DELETE_FAILEDRULE_EVALUATE_FAILEDRULE_GET_FAILEDRULE_LIST_FAILEDRULE_NOT_FOUNDRUN_NOT_FOUNDSAML_REGISTER_FAILEDSELF_REGISTRATION_CLOSEDSERVICE_NOT_REGISTEREDSETTINGS_ACTION_FAILEDSETTINGS_CRYPTO_UNAVAILABLESETTINGS_ENGINE_NOT_BOUNDSETTINGS_FORBIDDENSETTINGS_LOCKEDSETTINGS_UNKNOWN_KEYSETTINGS_UNKNOWN_NAMESPACESETTINGS_VALIDATIONSHARES_LIST_FAILEDSHARE_GRANT_FAILEDSHARE_REVOKE_FAILEDSHARING_NOT_ENABLEDSIGN_IN_REQUIREDSMS_SERVICE_REQUIREDSQL_DIALECT_EMISSION_UNSUPPORTEDSSO_REGISTER_FAILEDSSO_REGISTER_FORBIDDENSTACK_CAPABILITY_UNKNOWNSTACK_COMPOSE_ACTION_KEY_COLLISIONSTACK_COMPOSE_COLLECTION_CONFLICTSTACK_COMPOSE_FUNCTIONS_SHAPE_CONFLICTSTACK_COMPOSE_FUNCTION_CONFLICTSTACK_COMPOSE_KEY_CONFLICTSTACK_COMPOSE_OBJECT_CONFLICTSTACK_CROSS_REFERENCE_INVALIDSTACK_HIERARCHY_SCOPE_CAPABILITY_REQUIREDSTACK_NAMESPACE_PREFIX_INVALIDSTACK_PROVENANCE_MISSINGSTACK_SCHEMA_INVALIDSTACK_SINGLE_APP_VIOLATIONSTACK_TRIGGER_CAPABILITY_REQUIREDSTORED_TYPE_NOT_CANONICALSTORE_UNAVAILABLESUGGESTION_CONFIRM_FAILEDSUGGESTION_DISMISS_FAILEDSUGGESTION_LIST_FAILEDSUGGESTION_NOT_FOUNDSUGGESTION_STATESUMMARY_RECOMPUTE_FAILEDTENANT_SCOPE_REQUIREDTHROTTLEDUNAUTHORIZEDUNIQUE_SCOPE_CONFIRMATION_REQUIREDUNIQUE_VIOLATIONUNKNOWN_KEYUNKNOWN_NAMESPACEUNSUPPORTEDUNSUPPORTED_QUERY_PARAMUNSUPPORTED_TRANSFORMUPDATE_HOOK_RESULT_NOT_WRITE_SHAPEUPDATE_ID_MISMATCHUPLOAD_SESSION_EXPIREDUPLOAD_SESSION_NOT_FOUNDUSER_ALREADY_EXISTSUSER_ALREADY_EXISTS_USE_ANOTHER_EMAILVALIDATION_FAILEDVERSION_NOT_FOUNDVERSION_NOT_RESTORABLEWALLED_MEMBERSHIP_POLICY_UNDECLAREDWRITABLE_PACKAGE_REQUIREDWRONG_PASSWORD
ProvenanceWaiver
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| package | string | ✅ | The package whose source stamps the code without an owner-key row |
| code | string | ✅ | The registered code the package stamps |
| registeredUnder | string | ✅ | The owner key that deliberately carries the row instead |
| reason | string | ✅ | Why the stamping package carries no row — recorded so provenance is a decision, not drift |
StandardSynonymWaiver
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| code | string | ✅ | The registered extension code the waiver keeps admissible |
| shadows | Enum<'VALIDATION_ERROR' | 'INVALID_FIELD' | 'MISSING_REQUIRED_FIELD' | 'INVALID_FORMAT' | 'VALUE_TOO_LONG' | 'VALUE_TOO_SHORT' | 'VALUE_OUT_OF_RANGE' | … +42 more> | ✅ | The standard-catalog member whose condition the code re-spells |
| reason | string | ✅ | Why the synonym stays registered — recorded so admission is a decision, not drift |
Allowed Values: StandardSynonymWaiver.shadows
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_EXCEEDEDINTERNAL_ERRORDATABASE_ERRORTIMEOUTSERVICE_UNAVAILABLENOT_IMPLEMENTEDEXTERNAL_SERVICE_ERRORINTEGRATION_ERRORWEBHOOK_DELIVERY_FAILED