Use a Custom Error Element and Flow to Prevent Record Deletion.

Use a Custom Error Element and Flow to Prevent Record Deletion | Automate This!

By

Welcome to another “Automate This!” In this live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by Awesome Admin Trailblazers like you. With automation, you can remove manual tasks, drive efficiency, and eliminate friction and redundancy. In this episode, let’s see how Jeff Susich uses a record-triggered flow with a Custom Error element to prevent the deletion of accounts with associated opportunities or contacts.


Business need: We need to prevent account deletion

I work in a lot of different Salesforce orgs. As a consultant and a Salesforce trainer, I see a lot of variation in org setup, data, and how Salesforce professionals maintain their orgs. One difficult decision has always been what to do about duplicates. There are really two elements to duplicate records:

  • The duplicate records that currently exist in the org — This is usually from data importing, duplicate rules not being set up, or the matching rule logic not quite catching the duplicates.
  • The duplicates going forward from here — This can be greatly mitigated by using matching rules and duplicate rules.

Account duplicates are particularly troublesome. While a contact, for example, has unique fields such as email and mobile that can be used to identify duplicates, accounts have less unique fields to match on to identify duplicates. Is the address “1428 Elm Street” the same as “1428 Elm Street Apt 101”, indicating a duplicate?

But deleting accounts is a dangerous game. Salesforce is an account-centric CRM application. The Account object is parent to so many child objects, such as Contacts, Opportunities, Cases, etc. Similar to mountaineering teams that lash themselves together for safety but risk their team all going off the mountain, when an account is deleted, all those child object records go with it.

Profiles in a given org are frequently set up to not allow account deletion because of these factors. But, to be able to merge duplicate accounts, the user must be able to delete accounts, since that’s part of what happens in a merge of duplicate records.

Historically in Salesforce, if there was a business need to prevent deletion of records, Apex was required. But starting in Winter ’24, Flow and a new Custom Error element could be used to not only prevent certain records from being deleted but also show a personalized, more meaningful error message than available in validation rules to the user.

Salesforce has built-in system validation rules to prevent account deletion if they have any cases associated with them or have any won opportunities.

Our business requirement is that our users need to have the “Delete Accounts” permission to merge duplicate accounts. However, other accounts are being deleted. To address this, we’ll use Flow and Custom Error elements to prevent deletion of any account with any opportunities or contacts associated with them.

The solution: Record-triggered flow on delete with a Custom Error element

Let’s take a look at how we can accomplish this. We’ll use a record-triggered flow, triggered when an account record is deleted. Here’s the completed flow, which I’ll break down.

Configured record-triggered flow.

This record-triggered flow fires when an account is deleted. Are there alternate ways of doing this? Yes, but they present challenges and are not as efficient. We could create a roll-up summary field on the account to sum all opportunities, but roll-up summary fields are not available on the contacts of the account. Using a flow and Custom Error element gives us maximum efficiency as well as flexibility should the requirements change down the road.

We trigger the flow when an account record is deleted.

Note: The flow can perform actions before the triggering record is deleted — we are leveraging that.

Next, we use a Get Records element to retrieve any contact records associated with the account. We don’t need to sort them since we’re not displaying them. We only need to ascertain if there are ANY contacts on the account, and we need to save those records.

We used a Get Records element to get all the contacts associated with the account record that triggered the flow.

Next up, we use another Get Records element to get any opportunities associated with the account.

We use a Get Records element to get any opportunities associated with the account that triggered the flow.

At this point, we have any contacts or opportunities associated with the account in memory using the two Get Records elements. Now, it’s time for a decision. We have four possibilities:

  1. The account has both related contacts and opportunities, so we’ll prevent the account deletion.
  2. The account has related contacts, so we’ll prevent the account deletion.
  3. The account has related opportunities, so we’ll prevent the account deletion.
  4. The account has no related contacts or opportunities, so we’ll allow the account deletion.

We use a Decision element to check for all four possibilities. We check both the record collections from the Get Records elements to determine if there are any contacts or opportunities associated with the account. Then, we check for contacts only on the account, and no opportunities below.

We use a Decision element to determine if there are any contacts or opportunities on the account.

In the Contacts Only outcome, we address the situation in which there are contacts but no opportunities related to the account.

The Decision checks for there being contacts, but no opportunities, on the account.

In the Opportunities Only outcome, we verify that there are opportunities but no related contacts to the account.

This Decision path is taken if there are opportunities but no contacts on the account.

Finally, if there are neither contacts nor opportunities related to the account, we allow the deletion of the account. Our Decision element routes us to the respective Custom Error element for the three options in which there are either related contacts or opportunities to the account.

A Custom Error element is added to all three of the Decision paths that find related contacts or opportunities to the account.

The Custom Error element is then added to all three of the Decision paths that find a related contact or opportunity to the account. We then use the global variable $User to personalize the error message, and $Record to reference the account.

Personalized error message that uses global variables called $User and $Record.

We personalize the error message referencing their first name (to let them know we’re really empathetic). We display the error in a window dead center of the record page, which I find to be the best.

The error message displayed in a window right in the center of the page.

The exact message is just tweaked on the Decision paths to match if the path taken was for both related contacts and opportunities found, only related contacts found, or only related opportunities found.

Here again is our configured record-triggered flow.

A diagram of the fully built flow.

So, that’s how we used Flow to prevent the deletion of a record and show a personalized error message. Think of how much more powerful this is than validation rules. With some exceptions, we get access to only one object’s fields on a validation rule. Additionally, the error message on validation rules is text only; there’s no access to global variables such as $User or $Profile.

With Flow and Custom Error elements, we can use extremely detailed logic, using any objects we wish, to stop the deletion of records.

Resources

Want to see more good stuff? Subscribe to our channel!

SUBSCRIBE TODAY
Use Flows and Experience Cloud to Access Salesforce Scheduler.

Use Flows and Experience Cloud to Access Salesforce Scheduler | Automate This!

Welcome to another “Automate This!” In this live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by Awesome Admin Trailblazers like you. With automation, you can remove manual tasks, drive efficiency, and eliminate friction and redundancy. In this episode, learn how Lynn Guyer requests support from […]

READ MORE
Copy Files from One Object Record to Another.

Copy Files from One Object Record to Another | Automate This!

Welcome to another “Automate This!” In this live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by Awesome Admin Trailblazers like you. With automation, you can remove manual tasks, drive efficiency, and eliminate friction and redundancy. In this episode, see how Eric Smith created a subflow […]

READ MORE