Salesforce Flow is an automation tool that can be used to build complex business processes. There are numerous use cases and one of them is to build validations. There is a known workaround to use a before save record-triggered flow and mark a checkbox in order to fire validation rules. This is a great way to build complex validation rules. Although this technique was capable of building most of the validations that you may need, it was not possible to use it to prevent record deletion. It means that before delete record-triggered flow couldn't be used to block users from deleting records. In order to prevent record deletion, you had to use an Apex code.
Starting with the Winter '24 release, it is possible to display custom error messages directly from record-triggered flows. This means that you don't need to mark a checkbox in order to fire validation rules. Moreover, you can use the new custom error element in before delete record-triggered flows. This way, you can use flow to prevent record deletion.
Before Winter '24 Release
As mentioned above, before the Winter '24 release, you had to use Apex in order to prevent record deletion. Don't forget that you need a test class as well.
For instance, here is an Apex trigger that calls an Apex class in order to prevent active Account record deletion.
Apex Trigger
trigger AccountTrigger on Account (before delete) {
AccountTriggerHandler.preventDeletion(Trigger.old);
}
Apex Class
public class AccountTriggerHandler {
public static void preventDeletion(List<Account> accounts) {
List<Account> accountsToPreventDeletion = new List<Account>();
for (Account acc : accounts) {
if (acc.Active__c == 'Yes') {
accountsToPreventDeletion.add(acc);
}
}
if (!accountsToPreventDeletion.isEmpty()) {
for (Account acc : accountsToPreventDeletion) {
acc.addError('You cannot delete an active account!');
}
}
}
}
Let's see how to build this using a record-triggered flow.
After Winter '24 Release
1- Create a record-triggered flow on the account object. Configure to trigger the flow when a record is deleted and enter an entry condition.
2- Add a Custom Error element and enter an error message.
At the end, your flow should look like this.
As you can see, flow gives you the same result as Apex code.
Summary
After the Winter '24 release, it is possible to use a record-triggered flow in order to prevent record deletion. As you can see from this post, it is much easier than using Apex. Moreover, it is easier to make changes and maintain the process.
This is a more elegant solution than before. Thanks for sharing it, Yumi.
I think so. It is finally possible to prevent record deletion with flow! I had to use Apex for this simple request.
Can you tell me if this works to prevent record update? For example, if record picklist field is a specific value, then record cannot be updated.
Yes, sure. Do you want to prevent any update or just prevent changing the picklist value?
By the way, you can do it with a validation rule too.
I am trying to add a send email action after the custom error but the emails are not being sent. Would you know of any obvious reason because of which this may not work?
I tried to reproduce this and you are right, it is not sending the email.
It may be related to this, looks like it rolls back.
"If an executed fault path has a Custom Error element, the change that triggered the flow is rolled back."
You could put the email element after the decision or the start element but before the error element.
did this work for you or someone? still doesnt work for me the email sent even if actiongoes before error
Really useful and simple. Thank you.
Can we use this flow to prevent only for some profiles?
Yes, you can add the profile name (or any other criteria) to the start criteria of the flow.