Salesforce

Demystifying “cannot insert update” errors in Salesforce

Written by
Pablo Gonzalez
Business Engineering Architect
March 18, 2022
4
min read

Table of Contents

View all guides

Heading

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.

This is some text inside of a div block.

If you’ve been developing in Apex for a while, I’m sure you’ve come across the dreaded error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY.


In this post, I will explain what this error code stands for, when it happens, and how to investigate it (you’ll learn there isn’t a single fix).

Get started with Salto

Track critical changes to your Salesforce orgs

Try Salto free ≥

CANNOT INSERT UPDATE ACTIVATE ENTITY

Long story short, the error means: Something went wrong when trying to insert or update a Salesforce record, and thus the record was not committed to the database.

Let’s break it down word by word. First, Salesforce is telling us a record, like an account or an opportunity (ENTITY), could not (CANNOT) be inserted, updated, or activated (INSERT, UPDATE, ACTIVATE).

I’m not sure what ACTIVATE means in this context, but it’s pretty clear that INSERT and UPDATE refer to the process of creating or updating a record.

Put all that together, and you end up with CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, where the underscores represent spaces between each word.

When this occurs

This error mainly occurs when something goes wrong in an Apex trigger, but not all trigger failures will result in this specific error message. Let’s see a few examples (all of these are in the context of an Account trigger).

Mathematical errors

Let’s say you have the following piece of code in your trigger handler class:


When this trigger runs, I get the following error in the UI because it’s not possible to divide a number by zero:


Notice that even though the error happens in the trigger, we get a MathException instead of the CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY error.

Field validation errors

Let’s try the next version of our code:


Here, I’m trying to insert an empty contact record, which should fail because I haven’t provided a value for the required fields (LastName, etc.). When I run this code, here’s what I see:


Ok, so we still haven’t seen the infamous error.

Trigger infrastructure errors

Finally, let’s see what happens with the third version of our code:


This time, we are creating an empty account record. We just did this in the previous section with a contact. I was expecting this to fail with the validation error (just as with the contact), but lo and behold, this actually throws the CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY error.


I don’t know about you, but I’ve never been so happy to see this error!

How come we see this error when inserting an empty account (new Account()  ) but not when inserting an empty contact ( new Contact() )?

The reason is when we call new Account(), we are already inside the before insert trigger context, and calling new Account() creates a new trigger execution, before required fields are evaluated.

If we look at the Salesforce order of execution, we see that system validation rules (such as making sure that the required fields are populated) are executed only after before triggers are executed.


So what’s happening here is when an account record is inserted, we create another record, which fires the same trigger, creating another record, and so on. We never get the chance to get to step 5. We are in a loop between steps 1 and 4.

This results in the trigger being executed repeatedly until we hit the maximum trigger depth limit.

With new Contact(), the error is different because I don't have any contact triggers that are inserting other contacts in the same transaction, so we get to step 5 and we get an error stating that the LastName field is required.

I like to call this a trigger infrastructure failure because the source is a misconfigured trigger and not something wrong with the records themselves.

That said, I don’t think I can say with 100% certainty this error is reserved for trigger infrastructure failures, as other failures of this kind do not result in this error, for example:


What we are doing here is updating the same account that is being processed by the trigger. This results in the following error:


Here we get a SELF_REFERENCE_FROM_TRIGGER error, which basically means that we cannot update the record in the trigger inside a beforeUpdate trigger.

I would consider this a trigger infrastructure error, but we don’t see the CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY error. Why not? We’d have to ask Salesforce about that. :)

Process builder and flow

Finally, this error is also thrown when a flow/process fails during the execution of the trigger:


Here, the error message tells us a process or flow called Process Updating Field failed during the trigger execution.

So we know Salesforce can definitely throw the error in two scenarios:

  • Recursive trigger failures
  • Process and flow failures

Understand the impact of every change in your org

Try Salto free ≥

How to get rid of it

Now that we’ve established when this error occurs, we need to talk about making it go away.

Control recursion

The first part is to ensure you have recursive control on your trigger handlers. This basically means you need to be able to control how many times the same trigger is executed in a single transaction.

At a high level, this can be controlled by using a static variable in your trigger that can tell if the trigger has already been executed. Here’s a quick example.


That said, it’s best to implement this using an Apex trigger framework. For example, Kevin O’Hara’s trigger framework allows you to specify how many times a trigger can run.


This gives you a lot more flexibility than using a simple static variable.

Processes and flows

The second part is to look for any process/flows that could fail when inserting/updating a record. If an Apex trigger can indirectly invoke those processes/flows, make sure to wrap the invocation in a try/catch block:


So that’s it. Hopefully, this helped you get rid of this nasty error!

Until the next post.

Written by
Pablo Gonzalez

Pablo is a Business Engineering Architect at Salto. He is the developer of HappySoup.io and has 11 years of development experience in all things Salesforce.

Written by