⚠️ Work in progress — createCMS is pre-1.0 and not production-ready (not tested in production). Expect breaking changes.
Reference
Error codes
The CMS error codes, and how to detect them.
The CMS throws typed errors (CMSError, which extends better-call's APIError). Each has a stable code, an HTTP status, and a default message. Codes are defined in CMS_ERRORS (see packages/cms/src/core/errors.ts). Plugins add their own codes, merged into cms.$ERROR_CODES.
import { isCMSError, getCMSErrorCode } from '@createcms/core';try { await cms.api.pages.publishBranch({ body: { rootId, branchId } });} catch (err) { if (isCMSError(err, 'PUBLICATION_APPROVAL_REQUIRED')) { // handle this specific case } const code = getCMSErrorCode(err); // CMSErrorCode | undefined}
Function
Signature
Purpose
isCMSError
(error, code?) => error is CMSAPIError
Narrow an unknown error, optionally to one code.
getCMSErrorCode
(error) => CMSErrorCode | undefined
Read the code off an error.
CMSError
new CMSError(code, overrides?)
Construct or throw a CMS error by code.
These helpers work server-side, where errors are APIError / CMSError. The browser client throws a CMSClientError (a plain Error, not APIError), which isCMSError / getCMSErrorCode do not recognize. Detect it by its cmsCode:
import { CMSClientError } from '@createcms/core';try { await cmsClient.pages.publishBranch({ body: { rootId, branchId } });} catch (err) { if (err instanceof CMSClientError && err.cmsCode === 'PUBLICATION_APPROVAL_REQUIRED') { // handle this specific case }}
Block type is not allowed inside the target parent (violates the collection's structure rules or the parent's allowChildren)
PROTECTED_BRANCH
403
A direct content mutation was attempted on a published branch while branchProtection.protectPublishedBranches is enabled (edit via a separate branch + merge, or unpublish first)
COMMIT_MESSAGE_REQUIRED
400
A content mutation was made with no message while forceCommitMessage is enabled
COMMIT_NOT_FOUND
404
Commit not found
EMPTY_SNAPSHOT
400
Empty snapshot — no versions found
BLOCK_ALREADY_DELETED
400
Block is already deleted
TYPE_MISMATCH
400
Block type does not match the expected type
ROOT_HAS_CHILDREN
400
Cannot delete a page that has child pages; archive or move the children first
ROOT_IN_USE
409
Cannot delete: this root is embedded as a reusable block on live pages; remove those references first
CANNOT_MOVE_ROOT
400
Cannot move the root block
CANNOT_MOVE_INTO_SELF
400
Cannot move an item into itself
CANNOT_MOVE_INTO_DESCENDANT
400
Cannot move an item into its own descendant
CIRCULAR_REFERENCE
400
Cannot move a page under itself or one of its descendants
PARENT_ROOT_NOT_FOUND
404
Parent root not found in this collection
REFERENCE_DEPTH_EXCEEDED
422
Reference nesting is too deep (a reusable block embeds others past the limit)
MISSING_TARGET_PROPERTIES
400
targetProperties is required when duplicating a root