Skip to content

Reason Codes

Detailed page. Use “On this page” to jump directly to the section you need.

Identify the result status first, then use its Reason Code to choose the next action.

Use this page when a result, Flow output, metadata audit, or Lightning card returns a Reason Code. Find the code below to see what happened and which Salesforce configuration or access setting to check first.

Use this registry to translate a stable Reason Code into its status, meaning, and first useful investigation. Reason Codes let administrators, Flows, Apex, and integrations identify a cause without trying to interpret a message that an administrator can edit.

On the Lightning card, UNABLE_TO_EVALUATE appears as Unable to Check. To see an authorized diagnostic Reason Code, edit the Check Set in Setup → Custom Metadata Types → Record Health Check Set → Manage Records, select Show Diagnostics, and run as a user assigned Record Health Check Admin. Turn the setting off after the investigation.

Where you see itHow to use it
Lightning cardTurn on authorized diagnostics temporarily, then inspect applicability, dependencies, field access, Formula configuration, SOQL, or Apex
FlowRoute a known non-normal result without treating display text as an API
ApexBranch or log using a stable UPPER_SNAKE_CASE value
TroubleshootingConnect the public result with authorized Show Diagnostics details and logs

Reason Codes explain why a Check did not produce a normal PASS or FAIL, or why a card could not load. Codes use UPPER_SNAKE_CASE, and future package versions can add new codes. Integrations must use the code, never editable display text.

Public versus diagnostics-only: FIELD_NOT_ACCESSIBLE and RECORD_NOT_ACCESSIBLE never appear as the public reasonCode on a result. Record Health Check replaces them with CANNOT_EVALUATE. When Show Diagnostics is on and the user is assigned Record Health Check Admin or Record Health Check Diagnostics Viewer, the specific code is available in adminDetail.reasonCode.

Record Health Check uses a neutral public code because revealing whether a hidden record or field exists can disclose Salesforce access information to someone who is not allowed to see it. Authorized administrators still receive the specific cause through Show Diagnostics, where they can distinguish a missing record from missing field access without weakening the normal user’s security boundary.

The Apex helper for this two-code list is RecordHealthCheckReasonCodes. Other codes can come from the Apex classes that run Checks, merge-token handling, metadata validation, the Lightning card, or a custom Apex Check.


CodeTypical statusMeaning
NOT_APPLICABLE_BY_FORMULASKIPPEDApplicability mode WHEN_FORMULA_TRUE returned false.
NOT_APPLICABLE_BY_COUNTSKIPPEDApplicability count check was not met.
PREREQUISITE_NOT_METSKIPPEDPrerequisite Check did not return PASS.
STOPPED_AFTER_ERRORSKIPPEDClient stopped the remaining checks after a system error.
CLIENT_CALL_FAILEDERRORThe browser could not complete the Apex evaluation request.
MALFORMED_RESPONSEERRORApex returned a result that is missing required fields or uses an invalid format.
UNKNOWN_RESULT_STATUSERRORApex returned an unsupported result status.
MISSING_TOKEN_VALUEUNABLE_TO_EVALUATEA required merge-token value was unavailable.
CIRCULAR_DEPENDENCYUNABLE_TO_EVALUATETwo or more Checks depend on each other. The Lightning card can identify this before calling Apex.
DEPENDENCY_NOT_IN_RUNSKIPPEDThe Prerequisite Check was not included because it was inactive, missing, or outside the selected run. Display order does not control dependency scheduling.
APPLICABILITY_NOT_METSKIPPEDQuery empty-result path chose skip via NoRowsResult__c = SKIP (distinct from applicability checks above).
VALUE_IS_EMPTYSKIPPEDRow comparison skipped because a compared field value was empty under EmptyValueHandling__c = SKIP_RECORD.

CodeTypical statusVisibilityMeaning
CANNOT_EVALUATEUNABLE_TO_EVALUATEPublicNeutral substitute when a diagnostics-only access code is remapped.
FIELD_NOT_ACCESSIBLEUNABLE_TO_EVALUATEDiagnostics only (remapped publicly)Required field not readable in user mode.
RECORD_NOT_ACCESSIBLEUNABLE_TO_EVALUATEDiagnostics only (remapped publicly)A custom Apex Check or internal access check reported that the record could not be read.
RECORD_NOT_VISIBLEUNABLE_TO_EVALUATEPublicThe requested record was not returned by the user-mode record query. Confirm that the record still exists and the running user can access it.
NO_RECORD_CONTEXTUNABLE_TO_EVALUATEPublicEvaluation called without a usable record Id.

CodeTypical statusMeaning
CONFIG_NOT_FOUNDUNABLE_TO_EVALUATE / setupThe supplied Check Set QualifiedApiName was not found.
CONFIG_INACTIVEUNABLE_TO_EVALUATE / setupCheck Set is inactive.
OBJECT_MISMATCHUNABLE_TO_EVALUATE / setupCheck Set object does not match the record.
CHECK_NOT_FOUNDUNABLE_TO_EVALUATEThe supplied Check QualifiedApiName was not found in the resolved Check Set.
CHECK_INACTIVEUNABLE_TO_EVALUATECheck is inactive.
INVALID_CHECK_TYPEUNABLE_TO_EVALUATEEvaluation Type missing or unrecognized.
INVALID_CONFIGdefinition / unableInvalid Check Set display or identity configuration.
MISSING_REQUIRED_FIELDvalidationA required Check Set or Check field (e.g. Base Object API Name, Card Title) is blank.
FRAMEWORK_MAX_CHECKS_EXCEEDEDrequest / Lightning definition / validationA whole Check Set has more than 25 active Checks. Every entry point rejects the set before any Check runs. A request for one named Check remains independent.
APEX_DISPLAY_TEXT_IGNOREDvalidation warningAn Apex Check configures Display Found or Expected formulas/text. Custom Apex Check outcomes supply those values, so the metadata audit warns that these fields are ignored.
CONFIGURATION_IGNOREDvalidation warningA Check populates a field its Evaluation Type or mode never reads, such as a Source Query on a Formula Check or an Applicability Formula while Applicability Mode uses a count query. The value is not invalid, so the Check still deploys and runs; it simply has no effect. Clear the field, or change the Check so the field applies.
QUERY_FIELD_NOT_SELECTEDvalidationA query row token names a field the query’s SELECT list does not include. The message lists the fields the query does select.
QUERY_ORDER_NOT_DETERMINISTICvalidationA query row token addresses a row by position, but a potentially multi-row query has no explicit ORDER BY. Add a business order such as CreatedDate DESC.
QUERY_PROJECTION_NOT_ANALYZABLEvalidationThe token’s field cannot be proven from the readable outer projection. An independently selected scalar remains addressable beside an opaque child subquery.
QUERY_ROLE_NOT_AVAILABLEvalidationA comparisonRows token on a Check with no Comparison Query, or a row count against a query that counts records rather than returning them.
TOKEN_ROW_INDEX_INVALIDvalidationA row number that is not a whole number starting at 0, or one the Check can never reach: beyond the query’s own LIMIT, beyond Max Query Rows, or beyond the single row One Result and ungrouped aggregates return.
USER_RUN_PUBLICATION_UNREACHABLEvalidation warningAn automatic card hides Run and Rerun while Check Set publication is enabled. Users cannot publish from the card, but Apex and Flow remain available.
USER_RESULT_PUBLICATION_UNREACHABLEvalidation warningAn automatic card hides Run and Rerun while publication is enabled for one of its Checks. Users cannot publish from the card, but Apex and Flow remain available.
INVALID_DEPENDENCYvalidationPrerequisite metadata is invalid.
INVALID_OBJECT_API_NAMEthrown request errorThe selected Check Set has a blank or unknown Salesforce object API name.

CodeTypical statusMeaning
INVALID_SOQL_TEMPLATEUNABLE_TO_EVALUATESOQL template failed safety or parse checks.
FIELD_NOT_RESOLVEDUNABLE_TO_EVALUATEA configured field does not exist on the resolved Salesforce object. Correct the API name or remove the Check from orgs where that schema is unavailable.
FIELD_TYPE_NOT_SUPPORTEDUNABLE_TO_EVALUATEA selected field resolves but its value type cannot safely enter the Query comparison or result contract. Base64/Blob fields are refused before query execution; use reviewed user-mode Apex that owns binary handling without returning the binary value.
RELATIONSHIP_NOT_RESOLVEDUNABLE_TO_EVALUATEA configured relationship segment could not be resolved safely. Correct the relationship API name or traversal.
OBJECT_NOT_RESOLVEDUNABLE_TO_EVALUATEThe root object in a supported Query shape does not exist in the org. Correct its API name or remove the Check from orgs where that schema is unavailable.
MIXED_CURRENCYUNABLE_TO_EVALUATEReachable query values use more than one currency unit. Constrain the outer query to one ISO code, retain ISO grouping, or use Apex that explicitly owns unit handling. No conversion occurs.
CURRENCY_AGGREGATE_NOT_GROUPEDUNABLE_TO_EVALUATE / validationA Currency aggregate can combine units because the outer query neither groups by CurrencyIsoCode nor constrains every outer row to one ISO value. Fix the outer Source or Comparison Query; a filter inside a semi-join does not establish the outer unit.
FIXED_CURRENCY_BASIS_MISSINGUNABLE_TO_EVALUATE / validationA fixed threshold is compared with a Currency field without Expected Currency ISO Code. Set the ISO code that gives the fixed value its unit.
INVALID_OPERATORUNABLE_TO_EVALUATEComparison Operator is missing or cannot be used with the selected Evaluation Type and query-result setting.
INCOMPATIBLE_COMPARISON_TYPESUNABLE_TO_EVALUATEOrdered comparison cannot convert the two sides safely.
MULTIPLE_ROWS_RETURNEDUNABLE_TO_EVALUATEONE_RESULT expected one row/aggregate but got more.
NO_ROWS_RETURNEDUNABLE_TO_EVALUATEEmpty result handled as unable (NoRowsResult__c = UNABLE_TO_EVALUATE).
MISSING_BIND_VALUEUNABLE_TO_EVALUATEMerge token required for SOQL bind could not be resolved.
ROW_LIMIT_EXCEEDEDUNABLE_TO_EVALUATEA query returned more rows than that Check’s configured Max Query Rows cap. The result does not disclose the true row count. Narrow the query or raise the cap.
GOVERNOR_LIMIT_RISKUNABLE_TO_EVALUATERecord Health Check stopped before the query could use too much of the transaction’s remaining Salesforce limits. Reduce Max Query Rows, narrow the SOQL, or check fewer records per transaction.
UNSUPPORTED_BULK_QUERY_SHAPEUNABLE_TO_EVALUATEThe SOQL template cannot be converted to one query for all requested records. Rewrite it using a supported record-token pattern.
SCOPE_ROW_CAP_EXCEEDEDUNABLE_TO_EVALUATEThe bulk query returned more rows for the transaction than Record Health Check can safely process. Narrow the SOQL or lower the number of records checked per transaction.

CodeTypical statusMeaning
INVALID_FORMULAUNABLE_TO_EVALUATEFormula failed to compile/evaluate or returned a non-boolean where required.
DISPLAY_FORMULA_INVALIDUNABLE_TO_EVALUATEA Display Found or Display Expected formula could not be evaluated. Correct the formula and confirm its Formula Result Type.
FORMULA_EVAL_LIMITUNABLE_TO_EVALUATERecord Health Check stopped before the transaction reached Salesforce’s formula-evaluation limit. Reduce the number of records or Formula Checks evaluated together.
FORMULA_DEPENDENCY_DEPTH_EXCEEDEDUNABLE_TO_EVALUATEA calculated-field dependency chain exceeded the supported depth. Simplify the chain or replace the Check with a Query or Apex Check; Record Health Check will not evaluate when it could load only some required fields.

CodeTypical statusMeaning
APEX_CLASS_INVALIDUNABLE_TO_EVALUATEApexClass__c is not a simple class name or exactly namespace.ClassName. Remove embedded whitespace, extra dots, generic syntax, paths, or appended code.
APEX_CLASS_NOT_FOUNDUNABLE_TO_EVALUATEApexClass__c did not resolve to a visible Apex type. Confirm the class API name, packaging namespace, installation, and caller visibility.
APEX_CLASS_LOAD_FAILEDUNABLE_TO_EVALUATESalesforce raised an ordinary exception while loading the configured type. Authorized diagnostics retain the available cause.
INVALID_APEX_PARAMETERSUNABLE_TO_EVALUATEApexParametersJson__c is not a valid JSON object or does not satisfy the plugin parameter definition, including unknown or duplicate keys, nested values, wrong scalar types, invalid choices, or out-of-range values.
APEX_EVALUATOR_ERRORERROR / UNABLE_TO_EVALUATEPlugin execution raised an ordinary exception, including a failed user-mode query, or returned an illegal status or omitted required Found/Expected on PASS/FAIL.
PLUGIN_RESULT_MISSINGERROR (per record) or thrown Apex exceptionThe plugin returned no entry for a requested record, or returned a null map for the whole request. Cover every requested ID. An empty request should return an empty map.
PLUGIN_RESULT_UNKNOWN_KEYThrown Apex exceptionThe plugin returned an outcome for a record ID that was not requested. The complete custom Apex Check call fails.
PLUGIN_THREWThrown Apex exceptionThe plugin threw an unhandled exception that cannot be assigned to one record.
PLUGIN_CONSTRUCTOR_FAILEDUNABLE_TO_EVALUATEThe configured class was found, but Record Health Check could not construct it. Confirm that the class has an accessible no-argument constructor and that initialization does not throw.
PLUGIN_INTERFACE_INVALIDUNABLE_TO_EVALUATEThe class constructed but could not be cast to rhc.RecordHealthCheckPlugin in the form required by the installed package version.
PLUGIN_DEFINITION_INVALIDUNABLE_TO_EVALUATEThe optional plugin definition provider returned no definition, threw, queried business data, or declared an invalid schema. Correct the provider before evaluation.
PLUGIN_SCOPE_LIMIT_EXCEEDEDUNABLE_TO_EVALUATEThe applicable record scope exceeded the plugin definition’s declared capacity. Reduce the applicable scope or revise the reviewed capacity declaration.
PLUGIN_STATUS_INVALIDERRORThe plugin returned a status other than PASS, FAIL, SKIPPED, UNABLE_TO_EVALUATE, or ERROR.
PLUGIN_REASON_CODE_INVALIDERRORThe plugin returned a blank, overlong, or otherwise invalid Reason Code. Return a stable nonblank code of at most 80 characters.
PLUGIN_VALUES_MISSINGERRORA PASS or FAIL outcome omitted the required Found or Expected value.
PLUGIN_DISPLAY_INVALIDERRORPlugin display data did not satisfy the public display-value contract.
FRAMEWORK_UNEXPECTEDERRORThe framework reached an unexpected internal failure path. Capture the Diagnostic ID and contact the package administrator or support team.
PLUGIN_SIDE_EFFECT_DETECTEDThrown Apex exceptionThe plugin changed data, made a callout, sent email, published an event, or started asynchronous Apex. The transaction must not commit that action.
RECORD_NO_LONGER_AVAILABLECustom UNABLE_TO_EVALUATE / ERRORA custom Apex Check can return this when a record disappears between applicability and evaluation.
APEX_PASS / APEX_FAILCustom PASS / FAILThe installed AccountHasRecentActivityCheck example uses these codes. Custom Apex Checks may define their own stable Reason Codes.
OBJECT_NOT_FOUNDCustomAn example of a business-specific code that a custom Apex Check can return. Document every custom code used by your team.

PLUGIN_RESULT_UNKNOWN_KEY, PLUGIN_THREW, and PLUGIN_SIDE_EFFECT_DETECTED are Apex exceptions raised by RecordHealthCheckPluginDispatch. They are not ordinary per-record display outcomes. A null returned map uses PLUGIN_RESULT_MISSING as a thrown fault; a missing key for one requested ID becomes a per-record ERROR with that code.


CodeTypical statusMeaning
TOKEN_NAMESPACE_REQUIREDUNABLE_TO_EVALUATEToken omits the required namespace. See the example below the table.
UNSUPPORTED_TOKEN_NAMESPACEUNABLE_TO_EVALUATEToken namespace is not on the allowed list.
UNKNOWN_TOKEN_PROPERTYUNABLE_TO_EVALUATEToken property path is not recognized.
TOKEN_NOT_ALLOWED_ON_SURFACEUNABLE_TO_EVALUATEToken is used in a message, URL, or SOQL field that does not allow that token type.
TOKEN_NOT_AVAILABLE_IN_PHASEUNABLE_TO_EVALUATEToken needs a value that is not available at that point in the health check.
TOKEN_FORMAT_NOT_ALLOWEDUNABLE_TO_EVALUATEformat="..." is used outside display text or on a token other than record.*.
UNKNOWN_TOKEN_FORMATUNABLE_TO_EVALUATEformat="..." does not use one of the supported uppercase Value Format API names.
MALFORMED_TOKENUNABLE_TO_EVALUATEToken syntax is malformed.
TOKEN_LIMIT_EXCEEDEDUNABLE_TO_EVALUATEOne template contains more than 100 merge tokens. Split or simplify it so one message cannot create disproportionate field discovery and resolution work.
RESOLVED_TEMPLATE_TOO_LONGUNABLE_TO_EVALUATECompleted text exceeded 20,000 characters. Shorten the template or inserted Salesforce values; Record Health Check does not return partial guidance.

TOKEN_NAMESPACE_REQUIRED identifies a token that names a field without one of the documented namespaces:

{!Id fallback="not available"}

Rewrite it with the namespace, as {!record.Id}. Append a fallback only when a blank value needs a substitute, such as {!record.Name fallback="this record"}.


These often appear in card-level setup guidance rather than on a single Check row:

CodeMeaning
SETUP_REQUIREDNo Check Set selected, or availability check fell back to setup guidance.
NO_ACTIVE_CHECK_SETSNo Check Sets exist for the page object.
INACTIVE_CHECK_SETS_ONLYCheck Sets exist but none are active.
NO_ACTIVE_CHECKSSelected Check Set has no active Checks.
LOAD_FAILEDDefinition load failed without a more specific reason.

These values appear in a thrown Apex exception or a Flow error response rather than as the Reason Code for one record:

CodeMeaning
NOT_AUTHORIZEDThe running user does not have the Record Health Check Run Custom Permission.
INVALID_EVENT_PUBLICATIONApex or Flow supplied a value other than NONE, ACTIONABLE, or ALL.
MAX_RECORDS_PER_SCOPE_EXCEEDEDOne direct Apex or Flow request supplied more than 200 records. Use Batch Apex or divide the work.
FRAMEWORK_MAX_CHECKS_EXCEEDEDA direct Apex or Flow request selected more than 25 active Checks. Reduce the active Checks in the Check Set.
MAX_FLOW_GROUPS_EXCEEDEDOne Flow action call supplied more than 10 distinct Check or Check Set and Platform Event combinations. Divide the Flow inputs into fewer calls.
FLOW_RESPONSE_BUDGET_EXCEEDEDThe JSON results returned by one Flow action call exceeded 2,000,000 characters. Request fewer records or reduce display content.
PLUGIN_SAVEPOINT_BUDGET_EXCEEDEDThe planner throws this fault before evaluation when the selected custom Apex Checks would require more savepoint operations than the transaction can support. It is a stable message prefix, not a RecordHealthCheckReasonCodes constant or a per-record Reason Code. Run fewer Apex Checks together.
TRANSACTION_BUDGET_EXCEEDEDThe planned Checks and Platform Events would exceed a protected Salesforce transaction limit. Reduce the number of Checks or records in the transaction.
HEAP_BUDGET_EXCEEDEDThe planned response would require too much Apex memory. Reduce the number of Checks or records in the transaction.

  1. Branch automation on status first, then reasonCode.
  2. A future package version can add codes. Send an unknown code to a safe review path, or reject it when your process intentionally permits only a fixed list.
  3. Keep diagnostics-only codes out of unauthorized user views; trust the remapped public reasonCode.
  4. Log lines may mention events such as DEPENDENCY_NOT_PASSED; that is a log event name, not the public Check reasonCode (PREREQUISITE_NOT_MET is).