function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion

bug: custom validation rules prevent API updates to unrelated fields

Our product, Absolute Automation, updates custom fields on standard objects (Contacts, Leads, Accounts, etc).


Some of our customers have custom validation rules defined for those standard objects.


But custom validation rules have a serious problem: they prevent *any* update to an object that fails validation, even if the update in question has nothing to do with the validated fields. Because objects may pre-date the custom validation rules, this creates a number of "minefield" objects which cannot be updated until the validation error is fixed.


While this may make sense in a user interface context, it makes no sense in an API or code context, and even less sense in a managed packaged.

Let's look at a simplified example.

Starting with a standard test org with sample Contacts, let's define a new Custom Validation which requires that the Contact.FirstName field must be equal to "foo". Of course, all of our existing Contacts don't validate under that rule, but they pre-date the rule so they are already in the database (and SFDC does not prevent me from creating the rule, nor tell me that I have non-conforming objects in my system).


If, in the user interface, I go to update an unrelated field - say, Contact.Title - the validation failure does not let me update the Contact:


UI validation failure



Whether or not this makes sense is debatable - the user, after all, is not touching the FirstName field at all, so does it make sense to run the validation against it? If you think the answer is "yes", then it seems we should *also* require validation of all existing records when a Custom Validation rule is created.


But that's not the problem. The real problem is that this same error also prevents updates to unrelated fields in Apex Code.


Let's run an apex code snippet to update the Title of an existing Contact:


update new Contact(Id = '00370000016yOlu', Title = 'test');


Oops! Can't do it! The custom validation rule - which, again, is defined on a field that we are not even touching - prevents the update:


System.DmlException: Update failed. First exception on row 0 with id 00370000016yOluAAE; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, First name must be "foo"!: []


It becomes much harder to argue this is a good idea. If we are so militant about enforcing Custom Validations that we prevent *any* update to a non-conforming object until the validation is fixed, then SFDC shouldn't let me create Custom Validations unless every existing record conforms.


Now let's take it to the next level, and suppose that the Apex update is running in managed package code, and updating a custom field defined within that package. Now you're really getting crazy. Your lovely little app is now being sabotaged by validation rules that have nothing to do with your custom field update, and ... what are you supposed to do about it? You certainly don't know what the right values are to "fix" the validation failure. Instead, your updates just fail. Full stop. Did you want those updates? Sorry!

Essentially every single app on the AppExchange can assume very little about standard objects being updateable. Actually, at scale, you have to assume that you CANNOT update custom fields on standard objects, because at least one of your customers will have objects that don't pass their own Custom Validation rules.


Thus, any such update must be coded defensively: how important is this update? If I can't update this field, do I need to cancel the entire transaction? Or can I log the error & skip the field update, knowing that my data model is now somewhat inconsistent? If I let the entire transaction cancel - how can I ever retry it? It will just fail again with the same error. So before I retry my transaction, I have to contact my customer and ask them do either (a) turn off their validation rule, or (b) update their entire database to ensure legacy objects pass the newly defined validation.

Finally: what is the benefit of preventing my update? I'm not touching a field that is being validated (if I were, fine, it makes sense to prevent me from saving new, non-conforming data). Preventing the update doesn't help the object validate - fixing the object presumably will take human intervention, and that human is nowhere to be found when my code is executing. The only consequence of preventing these unrelated updates is that 3rd party apps and integrations are either much less reliable, or much less consistent. Zero upside, tons of downside.



Salesforce support - I have opened case 09799365 to track this issue.

Completely agree with you.
We cannot stop end users from creating new validation rules. These validation rules can in turn affect the processing of code in packages (or any related code).

One option would be to somehow have Salesforce run a check on all effected records on creation of a validation rule. This will ensure all effected records comply with the new rule.

Please let us know the about the updates in the case.

Satish Kumar


I think that checking all existing records at rule creation time would be too expensive, and would confront the user with too many rows that need updating. In addition, it wouldn't help with all the rules that already exist across the customer base.


My preferred solution be that, in all contexts, Salesforce only enforce validation rules when the validated fields are changing.  Wouldn't require any code changes by anyone, and the updated objects would be no less valid than they already were.  If SFDC wants to go the "extra mile" in the UI context & enforce validations on fields that aren't being updated, fine, but that should be the exception rather than the rule.

James Prevallet 10James Prevallet 10
Rather than program the API side defensively, I program the validation rules defensively.  For example, when I create validation rules I often start with an ISCHANGED() and ISNEW() checks to prevent the rule from firing if the field I'm targeting is not changing or if I don't care about having an ititial value when a row is added.  This works for many situtions but may not resolve all issues highlighted above.  
Eddy BakerEddy Baker
Due to the fact that our team consists of writers who have profound expertise in their fields, asking for our help is a very reasonable thing to do.