Error Codes
Every error in the CRUD bundle has a structured code:
CRUD-{DOMAIN}-{ACTION}-{REASON}- Domain — area of the app:
LISTING,FORM,DETAIL,IMPORT,MODAL,SIDEBOX - Action — what was attempted:
FETCH,DELETE,SAVE,RESET,SELECT,EXPORT,DUPLICATE - Reason — why it failed:
FAILED,EMPTY,LIMIT,NOT_FOUND,INVALID
Each error also has a 4-digit internal code for quick identification in logs and support tickets. Codes are grouped by domain:
| Domain | Range |
|---|---|
| LISTING | 1001–1099 |
| DETAIL | 2001–2099 |
| FORM | 3001–3099 |
| IMPORT | 4001–4099 |
| MODAL | 5001–5099 |
| SIDEBOX | 6001–6099 |
Every error toast includes a “Read docs →” link that jumps directly to the relevant anchor on this page.
Errors that receive a real server exception are automatically forwarded to Sentry with crud_error_code as a tag. Filter by it in Sentry to group errors by code.
Setup
1. Register the error catalog API route
import { crudErrorCatalogHandler } from
"@phpcreation/frontend-crud-react-nextjs-bundle/utils/errors";
export const GET = crudErrorCatalogHandler;Exposes GET /api/error-catalog — used by resolveError() to fetch CRUD error metadata at runtime.
2. Show inline error details with AppErrorRenderer
import { AppErrorRenderer } from
"@phpcreation/frontend-crud-react-nextjs-bundle/components";
<AppErrorRenderer error="CRUD-FORM-SAVE-FAILED" />Requires step 1 so resolveError() can reach /api/error-catalog.
3. Link toasts to this page
Set NEXT_PUBLIC_DOCS_BASE_URL to have error toasts include a “Read docs →” link:
NEXT_PUBLIC_DOCS_BASE_URL=https://dev.react-doc.phpr.linkWhen not set, toasts show the error message only — no link is generated.
4. Sentry tag filtering
Every showCrudError(code, message, originalError) call that receives an originalError argument tags Sentry:
scope.setTag("crud_error_code", "CRUD-LISTING-DELETE-FAILED");
scope.setContext("crud_error", {
code: "CRUD-LISTING-DELETE-FAILED",
message: "...",
domain: "listing",
});Filter in Sentry:
crud_error_code:CRUD-FORM-SAVE-FAILEDUser-interaction errors (e.g. “no items selected”) do not send to Sentry — only errors with a real originalError.
Listing Errors
CRUD-LISTING-FETCH-FAILED
| Field | Value |
|---|---|
| Internal Code | 1001 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to load listing data
When it occurs: The server action that fetches the resource collection returned an error. Triggered when getItemAction throws inside ListingContext.
Resolution:
- Reload the page to retry
- Verify the tenant and API configuration
- Confirm the user session is still valid
CRUD-LISTING-DELETE-FAILED
| Field | Value |
|---|---|
| Internal Code | 1002 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to delete the item
When it occurs: deleteItemAction returned an error for a single-item delete.
Resolution:
- Verify the user has
DELETEpermission on this resource - Check if the item is referenced by other entities (foreign key constraint)
- Inspect the API response for a specific message
CRUD-LISTING-BULK-DELETE-EMPTY
| Field | Value |
|---|---|
| Internal Code | 1003 |
| HTTP Status | 400 |
| UI Level | toast |
Message: No items selected to delete
When it occurs: Bulk delete triggered with zero items checked.
Resolution: Select at least one row using the checkboxes before triggering bulk delete.
CRUD-LISTING-BULK-DELETE-LIMIT
| Field | Value |
|---|---|
| Internal Code | 1004 |
| HTTP Status | 400 |
| UI Level | toast |
Message: You can only delete up to 20 items at a time
When it occurs: More than 20 items selected when bulk delete is triggered.
Resolution: Deselect items until 20 or fewer are checked, then retry in batches.
CRUD-LISTING-BULK-DISABLE-EMPTY
| Field | Value |
|---|---|
| Internal Code | 1005 |
| HTTP Status | 400 |
| UI Level | toast |
Message: No items selected to disable
When it occurs: Bulk disable triggered with zero items checked.
Resolution: Select at least one row before triggering bulk disable.
CRUD-LISTING-BULK-DISABLE-LIMIT
| Field | Value |
|---|---|
| Internal Code | 1006 |
| HTTP Status | 400 |
| UI Level | toast |
Message: You can only disable up to 20 items at a time
When it occurs: More than 20 items selected when bulk disable is triggered.
Resolution: Reduce selection to 20 or fewer items, then retry in batches.
CRUD-LISTING-BULK-EDIT-FAILED
| Field | Value |
|---|---|
| Internal Code | 1007 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to edit one or more items
When it occurs: updateItemAction returned an error during a bulk edit operation.
Resolution:
- Reload the listing and verify which items were updated
- Check the user’s edit permissions on the affected resource
- Inspect the API error for validation details
CRUD-LISTING-SELECTION-LIMIT
| Field | Value |
|---|---|
| Internal Code | 1008 |
| HTTP Status | 400 |
| UI Level | toast |
Message: You can only select up to 20 items
When it occurs: Trying to check a 21st item in the listing table.
Resolution: Deselect some items before adding new ones to the selection.
CRUD-LISTING-KVS-FIELDS-SAVE-FAILED
| Field | Value |
|---|---|
| Internal Code | 1009 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to save listing fields preference
When it occurs: The KVS API call that persists the user’s visible-columns configuration failed.
Resolution:
- Verify
NEXT_PUBLIC_KVS_API_RESOURCE_NAMEandNEXT_PUBLIC_KVS_DATA_STORE_TOGGLEare set - Check the user has write permissions on the KVS endpoint
CRUD-LISTING-KVS-INTERFACE-SAVE-FAILED
| Field | Value |
|---|---|
| Internal Code | 1010 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to save listing interface preference
When it occurs: The KVS API call that persists the full listing interface (columns, actions, pagination) failed.
Resolution: Same as CRUD-LISTING-KVS-FIELDS-SAVE-FAILED above.
CRUD-LISTING-KVS-INTERFACE-RESET-FAILED
| Field | Value |
|---|---|
| Internal Code | 1011 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to reset listing interface
When it occurs: The KVS delete request for the saved interface entry returned an error.
Resolution:
- Check the user has delete permissions on the KVS endpoint
- Refresh and retry the reset
CRUD-LISTING-KVS-INTERFACE-RESET-EMPTY
| Field | Value |
|---|---|
| Internal Code | 1012 |
| HTTP Status | 404 |
| UI Level | toast |
Message: No saved interface found to reset
When it occurs: Reset triggered but no KVS entry exists for this listing’s interface.
Resolution: Save the interface at least once using Save interface before attempting a reset.
CRUD-LISTING-DUPLICATE-FAILED
| Field | Value |
|---|---|
| Internal Code | 1013 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to duplicate item
When it occurs: handleListingDuplicate in useActionButtons threw an error when calling getItemAction on the duplicate endpoint.
Resolution:
- Verify the user has
CREATEpermission on this resource - Check the API response for the root cause
CRUD-LISTING-INLINE-SAVE-FAILED
| Field | Value |
|---|---|
| Internal Code | 1014 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to save inline edit
When it occurs: An inline cell edit was rejected by the API or an unexpected exception occurred during the update.
Resolution:
- Verify the entered value is valid for this field type
- Use the full edit form if the problem persists
- Check the browser console for more detail
CRUD-LISTING-MASS-UPDATE-FAILED
| Field | Value |
|---|---|
| Internal Code | 1015 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Mass update failed
When it occurs: The updateItemAction call inside the mass update handler returned an error or threw an exception.
Resolution:
- Reload the listing and verify which items were updated
- Check the user’s edit permissions on the affected resource
CRUD-LISTING-EXPORT-NO-DATA
| Field | Value |
|---|---|
| Internal Code | 1016 |
| HTTP Status | 400 |
| UI Level | toast |
Message: No data to export
When it occurs: Export triggered but the listing has no loaded data.
Resolution:
- Wait for the listing to finish loading
- Remove filters that may be returning zero results
CRUD-LISTING-FILTERS-SAVE-FAILED
| Field | Value |
|---|---|
| Internal Code | 1017 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to save filter configuration
When it occurs: The KVS API call that persists the active filter configuration failed in DefaultFiltersMenu.
Resolution:
- Verify
NEXT_PUBLIC_KVS_API_RESOURCE_NAMEandNEXT_PUBLIC_KVS_DATA_STORE_TOGGLEare set - Check the user has write permissions on the KVS endpoint
CRUD-LISTING-KANBAN-UPDATE-FAILED
| Field | Value |
|---|---|
| Internal Code | 1018 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to update item status
When it occurs: Moving a Kanban card to a new column triggered an updateItemAction that returned an error. The board refreshes to the last known state.
Resolution:
- Verify you have edit permission on this item
- Check the API response for validation details
CRUD-LISTING-ANCHOR-NOT-FOUND
| Field | Value |
|---|---|
| Internal Code | 1019 |
| HTTP Status | 404 |
| UI Level | toast |
Message: Anchor item not found in current page
When it occurs: The URL contains an anchor query parameter with an item ID not present in the current page results — item deleted, filtered out, or on a different page.
Resolution:
- Remove the
anchorparameter from the URL - Check if the item was deleted or hidden by the current filters
CRUD-LISTING-ORDER-UPDATE-FAILED
| Field | Value |
|---|---|
| Internal Code | 1020 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to update item order
When it occurs: The updateItemAction call to update priority or lft/rgt tree positions returned an error.
Resolution:
- Reload the listing to get the current server order
- Verify the resource supports ordering (
sortable: truein column config) - Check the API response for the root cause
Detail-Show Errors
CRUD-DETAIL-DELETE-FAILED
| Field | Value |
|---|---|
| Internal Code | 2001 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to delete item
When it occurs: handleDelete in useActionButtons threw an error when calling deleteItemAction from the detail/show page.
Resolution:
- Verify the user has
DELETEpermission on this resource - Check if the item is referenced by other entities (foreign key constraint)
- Inspect the API response for a specific message
CRUD-DETAIL-DUPLICATE-FAILED
| Field | Value |
|---|---|
| Internal Code | 2002 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to duplicate item
When it occurs: handleDuplicate in useActionButtons threw an error on the detail page.
Resolution:
- Verify the user has
CREATEpermission on this resource - Check the browser console and API response for details
CRUD-DETAIL-EXPORT-NO-DATA
| Field | Value |
|---|---|
| Internal Code | 2003 |
| HTTP Status | 400 |
| UI Level | toast |
Message: No data to export
When it occurs: Export triggered before the detail page item data finished loading.
Resolution: Wait for the detail page to fully load, then retry.
CRUD-DETAIL-EXPORT-NO-FIELDS
| Field | Value |
|---|---|
| Internal Code | 2004 |
| HTTP Status | 400 |
| UI Level | toast |
Message: No fields configuration for export
When it occurs: Structured export (CSV/Excel) triggered but no fields prop passed to ShowHeaderActions.
Resolution: Pass a fields array to ShowHeaderActions. Alternatively, use the raw JSON export which does not require field definitions.
CRUD-DETAIL-EXPORT-FAILED
| Field | Value |
|---|---|
| Internal Code | 2005 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to export data
When it occurs: An unexpected error occurred while generating the export file in handleExport.
Resolution:
- Try the raw JSON export option
- Check the browser console for error details
Form Errors
CRUD-FORM-SAVE-FAILED
| Field | Value |
|---|---|
| Internal Code | 3001 |
| HTTP Status | 422 |
| UI Level | toast |
Message: Failed to save
When it occurs: res.error returned by createItemAction or updateItemAction in EditEntityForm, AddEntityForm, QuickEdit, or QuickAddModal.
Resolution:
- Read the appended server message in the toast — it usually contains the specific field validation error
- Correct the highlighted fields and resubmit
- Confirm all required fields are filled
CRUD-FORM-EXCEPTION
| Field | Value |
|---|---|
| Internal Code | 3002 |
| HTTP Status | 500 |
| UI Level | toast |
Message: An error occurred
When it occurs: An unhandled JavaScript exception thrown inside the form save handler (catch block in EditEntityForm or AddEntityForm).
Resolution:
- Open the browser console — the full stack trace is logged there
- This is distinct from an API validation error; check for null references or missing data
CRUD-FORM-TRANSLATIONS-FETCH-FAILED
| Field | Value |
|---|---|
| Internal Code | 3003 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to load translation data
When it occurs: The translations API call in getTranslatableData returned an error. Only triggered when the form is configured as translatable: true.
Resolution:
- Reload the page to retry fetching translations
- Verify the translations API endpoint is accessible
- The form can still be submitted without pre-existing translations loading
Import Errors
CRUD-IMPORT-FILE-INVALID
| Field | Value |
|---|---|
| Internal Code | 4001 |
| HTTP Status | 400 |
| UI Level | toast |
Message: Please upload a CSV file
When it occurs: A non-CSV file selected or dropped into the import modal.
Resolution: Export your data as .csv from the source system and re-upload.
CRUD-IMPORT-FILE-READ-FAILED
| Field | Value |
|---|---|
| Internal Code | 4002 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Error reading file
When it occurs: The browser’s FileReader API triggered onerror — the file could not be read.
Resolution:
- Ensure the file is not open or locked in another application
- Try saving it to a different location and uploading again
- Open the file in a text editor to verify it is not corrupt
CRUD-IMPORT-CSV-PARSE-FAILED
| Field | Value |
|---|---|
| Internal Code | 4003 |
| HTTP Status | 400 |
| UI Level | toast |
Message: Error parsing CSV file
When it occurs: The CSV parsing logic threw an exception — the file content could not be decoded with the configured delimiters.
Resolution:
- Verify the field delimiter and text delimiter match those used in the CSV
- Open the file in a text editor to check its raw structure
- Re-export using standard settings (comma-delimited, double-quote text)
CRUD-IMPORT-JOB-FAILED
| Field | Value |
|---|---|
| Internal Code | 4004 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to import data
When it occurs: The server returned an error while creating or executing the import job in EditListingImportModal.
Resolution:
- Verify the CSV matches the expected column structure for this resource
- Check user permissions for import operations
- Inspect the API response for validation details
Modal Errors
CRUD-MODAL-KVS-SAVE-FAILED
| Field | Value |
|---|---|
| Internal Code | 5001 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to save default form values
When it occurs: The KVS API call that saves the default form field values in DefaultFlagModal returned an error.
Resolution:
- Verify
NEXT_PUBLIC_KVS_API_RESOURCE_NAMEis set - Check the user has write permissions on the KVS endpoint
CRUD-MODAL-KVS-RESET-FAILED
| Field | Value |
|---|---|
| Internal Code | 5002 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to reset default form values
When it occurs: The KVS delete request for the saved defaults entry failed in DefaultFlagModal.
Resolution:
- Check the user has delete permissions on the KVS endpoint
- Refresh and retry the reset
CRUD-MODAL-DUPLICATE-FAILED
| Field | Value |
|---|---|
| Internal Code | 5003 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to duplicate item
When it occurs: Either the initial fetch (getItemAction) or the save (createItemAction) in QuickDuplicateModal returned an error.
Resolution:
- Verify the user has
CREATEpermission on this resource - Check the API response for validation details
CRUD-MODAL-FILTER-SAVE-FAILED
| Field | Value |
|---|---|
| Internal Code | 5004 |
| HTTP Status | 500 |
| UI Level | toast |
Message: Failed to save filter
When it occurs: An error thrown while saving a new filter configuration in AddFilterModal.
Resolution:
- Verify the filter configuration is valid
- Check the browser console for more detail
Sidebox Errors
CRUD-SIDEBOX-NO-FORM-INPUTS
| Field | Value |
|---|---|
| Internal Code | 6001 |
| HTTP Status | 400 |
| UI Level | toast |
Message: No form inputs defined for this resource
When it occurs: The sidebox attempted to open a Quick Add modal but formInputsAdd was not configured. The user is redirected to the standard add page as a fallback.
Resolution:
- Pass
formInputsAddto theSideboxcomponent for this resource to enable quick-add - If the redirect to the standard add page is acceptable, this toast can be ignored
UI Display Levels
Each error specifies a ui.level that controls how it renders:
| Level | Description |
|---|---|
toast | React-hot-toast notification — disappears after 5s |
component | Renders an ErrorCard inline below the affected area |
modal | Opens an ErrorModal overlay |
page | Replaces the page with a full-screen error page |
field | Renders an inline error next to a specific form field |
All current CRUD bundle errors use toast.
Adding New Error Codes
Bundle (catalog.ts)
// 1. Add the entry to the catalog
"CRUD-MYFEATURE-ACTION-FAILED": {
code: "CRUD-MYFEATURE-ACTION-FAILED",
internalCode: 7001, // next available in your domain range
httpStatus: 500,
domain: "crud-v2",
ui: {
level: "toast",
message: "Human-readable message shown in the toast",
action: "What the user should do",
},
docs: {
slug: "CRUD-MYFEATURE-ACTION-FAILED",
message: "Same or expanded message for the docs page",
description: "Detailed explanation of root cause.",
actions: [
{ label: "Step 1 to resolve" },
{ label: "Step 2 to resolve" },
],
},
},// 2. Call it — pass the original exception as 3rd arg to tag Sentry
import { showCrudError } from "@phpcreation/frontend-crud-react-nextjs-bundle/utils/errors";
// User-action error (no Sentry)
showCrudError("CRUD-MYFEATURE-ACTION-FAILED");
// Server/exception error (tags Sentry with crud_error_code)
showCrudError("CRUD-MYFEATURE-ACTION-FAILED", res.error, originalException);