Tuesday, February 15, 2022

Interesting DML Error in Salesforce Flows

 I recently saw an interesting error in one of the projects:

This error occurred: DUPLICATE_VALUE: Maximum number of duplicate updates in one batch (12 allowed). Attempt to update Id more than once in this Api call: record Id.

It came from a flow that has been running smoothly for a long time. The documentation https://help.salesforce.com/s/articleView?id=000314518&type=1 doesn't really explain my issue, because I don't have any scheduled actions or a wait element.

After some digging, I realize that if you try to update the same record multiple times in one transaction, then you may face this issue. In my case, I have flow automation on the child object that updates the corresponding parent object. When the parent has many children records (more than 12) and the values to be updated on the parent are different, I see this error. For example, the parent has 20 children namely: 1, 2, 3 ... 20, and each child is updating a text field on the parent using their own name, so the same transaction can end up assigning 1, 2, 3 ... 20 to the parent record's text field, and triggering the above error. If they update the parent in the same way (assigning the same value for the field), then there won't be any error, and that's what I missed in the past without knowing this potential issue.

Once the root cause has been determined, I can start to figure out a fix. The goal is quite simple, to avoid this recursive automation. So depending on the use case we need to add a decision element to check that field to update in the flow. For example, I want to save the maximum number then I need to compare the existing value and the target value in this decision node, if the existing value is greater than or equal to the target value, then the flow ends instead of continuing to update the parent record.

Interestingly I tried to replace the original logic with a trigger (without the decision part) using the code below, there is no error at all. 

trigger triggerContactName on Contact (after insert, after update) {

    List<Id> ids = new List<Id>();

    for (contact con: trigger.new){

        ids.add(con.accountId);

    }

    

    Map<Id, Account> accs = new Map<Id, Account>([Select Id, site From Account Where Id in: ids]);

    for (contact con: trigger.new){

        accs.get(con.accountId).site = con.lastName;      

    }

    update accs.values();

}

My understanding is that behind the scenes Salesforce isn't really bulkifying flows in the same way of using maps in my trigger. It may just list the record multiple times and update once, hence the maximum number of 12. 

This error reminds me of another error I faced a while ago, which is worth mentioning as well.

System.TypeException: Cannot have more than 10 chunks in a single operation. Please rearrange the data to reduce chunking.

This one is also interesting because the chunk is essentially a list of records of the same object, but as indicated in the error message, the sequence matters. So we should try to keep the records of the same object together to avoid this issue. For example, the following 2 snippets are doing the same thing, but the 1st one will trigger the error, and the 2nd one works fine.

Mixed pattern:

list<sObject> records = new list<sObject>();

for (integer i=0; i<20; i++) {

    Account acc = new Account (name = 'Test' + i);

    Contact con = new Contact(lastname = 'Test' +i);

    records.add(acc);

    records.add(con);

}

insert records;

Sorted pattern:

list<sObject> records = new list<sObject>();

for (integer i=0; i<20; i++) {

    Account acc = new Account (name = 'Test' + i);

    records.add(acc);

}


for (integer i=0; i<20; i++) {

    Contact con = new Contact(lastname = 'Test' +i);

    records.add(con);

}

insert records;

Flows are great, but we need to be careful about these little traps. As I recently learned, error handling is an absolute must everywhere, because the automation will fail, it's never a question of if it fails, but when it fails :)

No comments:

Post a Comment

Tips for Salesforce Certified Strategy Designer Exam

A little late to the party, but I just passed the latest Strategy Designer exam. Since it's a really new one (about one week old), there...