Level Up Your Approvals with Flows and the Custom Error Element.

Level Up Your Approvals with Flows and the Custom Error Element | 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 Jon Chen designs a solution for a highly customized approval process that limits approvals to certain users.

Business case

A financial services client needed a customized approval process with several key requirements.

  • Only Managing Directors can update the Status field on the Account object to one of two values: ‘High Value’ or ‘Ultra HNW’.
  • Associates must submit accounts for approval, select any Managing Director as the approver, and select which status value they are requesting.
  • Only Managing Directors can approve accounts.
  • After approval, automatically update the Status field to the requested value.
  • When an account is pending approval, do not allow any field changes to the account or another approval to be submitted.
  • Because the legacy org has a multitude of custom fields already on the Account object, only create new fields when necessary.

My approach

Start with out-of-the-box first

I like to start my solutions using as much out-of-the-box functionality as possible, so I first evaluated whether or not a combination of native, non-flow configuration components would adequately meet the requirements. Approval processes were the obvious choice and would allow for approval requests and lock the record from field changes. A validation rule would help restrict field updates to only Managing Director users, which, for this client, were identified by the Title field on the User record.

However, the two requirements that stood out as likely needing customization were allowing associates to choose any Managing Director and automatically updating the record dynamically based on a status selection.

Note on Title field:
While I’m demonstrating referencing the standard Title field on the User object, it may make more sense in other scenarios to reference Profile, Role, or Custom Permission via a permission set. For this client, I ended up creating an additional validation rule on the User object to prevent users from updating their title.

Use a validation rule to restrict updates

I created a validation rule on the Account object to restrict associates from updating the Status field to either ‘High Value’ or ‘Ultra HNW’.

Validation rule that prevents updates to the Status field for users with ‘Associate’ in their title.

Apply dynamic actions to show relevant actions to users

Next, I needed a way to conditionally show the approval submission quick action only to Associate users and hide it after an approval was requested. This is a perfect fit for dynamic actions in the Lightning App Builder. In order to utilize this feature, I needed to create a custom picklist field on the Account object called ‘Approval Status’. This ended up being the only custom field I created for the entire solution, which met the last requirement and gave me brownie points with the System Administrator.

I set the dynamic actions visibility to only show if the approval status is not equal to ‘Pending’ and the user’s title does not contain ‘Managing Director’.

Dynamic actions visibility for Request Approval set to when the Approval Status is not equal to ‘Pending’ and the Title does not contain ‘Managing Director’.

Unlike reports, dynamic actions is currently limited to the operators ‘Equals,’ ‘Not Equal’, and ‘Contains’, so I needed to use filter logic and place ‘NOT’ before the filter condition with the ‘Contains’ operator as a workaround for ‘does not contain’. To configure the dynamic actions, I needed to decide on whether to use the standard Submit for Approval action or create a quick action that launched a screen flow.

Evaluate the approval processes’ capabilities against requirements

Before committing to building a screen flow, I did my due diligence and confirmed that the out-of-the-box Submit for Approval quick action would not suffice. Being experienced in using approval processes, I was familiar with the option of Manually Chosen which requires submitters to select a user to serve as the approver during submission. Unfortunately, there is no current functionality to set a filter or define conditions for eligible approvers. Shown in the screenshots below, the standard action also does not allow for adding additional fields to the submission screen.

Out-of-the-box Submit for Approval first screen with a text box for comments.


Out-of-the-box Submit for Approval second screen with a lookup field to choose next approver.

While these limitations meant that the standard action for approval processes wouldn’t cover all the requested functionality, I recognized key functionalities within approval processes that the client could still benefit from.

  • Locking the record to prevent field changes
  • Object model and automatic approval record creation
  • Approval history reporting
  • Native approval request page and actions for approving, rejecting, etc.
  • Salesforce notifications and automated emails based on Classic Email Templates

Approval Salesforce notification of an approval request.

This is the Approval Request page, a native feature within approval processes.

Approval Request page with fields on the left and comments on the right.

The above features would all fit the client’s business case well and save a lot of trouble from the alternative of building out a completely custom approval solution with custom objects, actions, pages, and automations. It was an easy decision to leverage approval processes, but now I faced the challenge of building a custom approval submission experience.

Create a screen flow to customize the approval submission

I knew there was a Submit for Approval action available in flows which submits a record into an approval process, so I started designing the screen flow at the end and worked backwards. Prior to the submission action, I needed to validate that the user selected for approval had ‘Managing Director’ in their title. Of course, that required the previous screen to allow users to select the approver as well as the desired status value.

Because the record would be locked after entering the approval process, I also needed to use an Update Records element to set the Account to the ‘Pending’ approval status. Having the Update Records element come before the Submit action was important, as the requestor would receive an error if the flow tried to update the account after the record has been locked. While switching the flow to system context would bypass the error, I would typically reserve that for screen flows with specific purposes that require opening up permissions. While running in system context, the flow respects organization-wide default settings, role hierarchies, sharing rules, manual sharing, teams, and territories, but it doesn’t respect object permissions, field-level access, or other permissions of the running user. An alternative approach would be to add a Field Update to the approval process Initial Submission Actions to update the status to ‘Pending’, but I figured it would save a metadata component to include the Update Records element in the screen flow.

How the screen flow turned out:

Custom approval request screen flow view from Flow Builder.

Screen flow with validation formula on lookup field highlighted.

The first Screen element has a picklist field, a long text area for comments, and a lookup component, which contains a validation check with a formula (1) that shows an error if the associate selects themselves.

{!Approver.recordId} != CASESAFEID({!$User.Id})

Quick tip:
Use the CASESAFEID function to use the full 18-character ID whenever referencing the {!$User.Id} global variable since Salesforce gives the 15-character ID by default.

When writing the formula, I had to remind myself that flow user input validation is the opposite of validation rules, so that the error message is shown only when the formula is not met.

After the Get Elements element retrieved the selected approver’s User record, the Decision element checks whether the Title field of the user includes ‘Managing Director’. Instead of ‘Equals’, I used the ‘Contains’ operator because I knew it was common for this client to have users with multiple titles (for example, managing director and principal).

For the Submit for Approval action, I created a formula to combine the values of the Requested Status and the Comments components from the initial screen and populate the Submission Comments, for reasons which I’ll expand on further below.

This is an example of a Salesforce notification, which is a native feature within approval processes.

Flow formula for Approval Comments which combines the Requested Status and Comments inputs.

Quick tip:
To include a line break when populating a long text area field in flows, watch this explanation from Christi Kane which I was fortunate enough to come across.

This is the screen associates see when submitting a ‘High Value’ approval request.

End-user view of screen flow with input fields for Requested Status, Select Approver, and Comments.

A simple error screen with merge fields appears if the approver (User) selected has a title that doesn’t contain the text ‘Managing Director’. The only navigation option is ‘Previous’ to allow the associate to navigate back to the initial screen and select another approver.

Screen flow screen showing error message when selecting a non-eligible approver.

Finally, it’s good practice to include a confirmation screen to inform users that their action was successful. This one contains a few merge fields with the Account Name and the name of the approver.

Screen flow confirmation screen that the approval request has been submitted.

Create the approval process

If you’re new to approval processes or could use a refresher, learn more about how they work on Trailhead (There’s even a superbadge!).

For the approval process I created, I only needed one step which is set to ‘Manually Chosen’ for the Assigned Approver. I also created two Field Updates, one for the Final Approval Actions and the other for the Final Rejection Actions. These update the newly created Approval Status field to ‘Approved’ or ‘Rejected’.

Approval Process page configured with one approval step and two field updates.

While approval processes can only launch four types of actions, which does not include flows (upvote this Idea!), the workaround is to use a Field Update and create a record-triggered flow based on that field.

Build a record-triggered flow for automatic record updates

So now we’re validating that the associate is selecting a Managing Director to approve the request. But how do I make sure the user actually approving the request is a Managing Director? With approval processes, a reassign button exists and is currently not able to be removed from the screen (upvote this Idea), so Managing Directors could potentially reassign approval requests to other users or system administrators could also attempt to approve the request.

Enter the Custom Error element, which is available in record-triggered flows! I wasn’t positive it would work correctly but decided to try to utilize it for an approval process.

Record-triggered flow with an error element in the Non-Managing Director path and Get and Update elements in the Yes — Managing Director path

The entry conditions on this are to trigger the flow when a record is updated and the condition of the Approval Status field equals ‘Approved’. It’s important to select ‘Only when a record is updated to meet the condition requirements’ so that the flow doesn’t run every time a field value on the account is updated. Finally, after some testing with approval processes, I figured out this needed to be a Before Save (Fast Field Updates) flow so that the error runs prior to the record saving.

For the record-triggered flow, because the client requested to be selective in creating new fields, we’re able to retrieve the Requested Status value from the submission comments of the approval request. To do so requires a high-level understanding of the data model for approval processes. The way I would describe it is that the ProcessInstance object represents every time a record enters an approval process and is made up of ProcessInstanceStep records that capture the details of each step, including the Comments.

Entity Relationship Diagram for approval processes.

After validating the approver is a Managing Director, I have a Get Records element on the ProcessInstance object, which is sorted by descending order on CreatedDate so that the most recent ProcessInstance record is retrieved. Technically, records could potentially enter the same or multiple approval processes more than once, so this criteria will make sure we only get the record for the current pending approval.

Flow Get Records element on ProcessInstance object with TargetObjectId equal to Record ID sorted by descending CreatedDate.

Then, I used a Get Records element on the ProcessInstanceStep object, which is also sorted by CreatedDate in descending order and includes the StepStatus of ‘Started’ (the API name of Submitted). Now we’re able to evaluate the values that were stored in the Comments when the approval request was submitted.

Flow Get Records element on ProcessInstanceStep object with ProcessInstanceId equal to previous Get Records variable, and StepStatus equal to Started and sorted by descending CreatedDate.

Lastly, we have an Update Records element to update the account’s Status field to the requested value. Here, I’m using a simple formula with the ‘Contains’ operator to evaluate which status value was requested, but other use cases may require more specific formulas using the FIND() and MID() operators.

And with that, we’re now automating the account status update to the requested value, meeting the last of our requirements!

Flow formula for RequestedStatusValue using the Contains operator on keywords ‘High Value’ and ‘Ultra HNW’.

Let’s recap the solution

The client had specific requirements for their approvals, which out-of-the-box approval processes did not support. To create a customized approval submission experience and automate the account update dynamically, we used one validation rule, one screen flow, one quick action with dynamic actions, one approval process with two workflow field updates, and one record-triggered flow.

  • Validation Rule: Restricts updates of Status field to specific values.
  • Screen Flow + Quick Action + Dynamic Actions: Enables a custom approval experience for associates to submit approval requests.
  • Approval Process with Workflow Field Update: Locks records, tracks approval requests, and indirectly launches a record-triggered flow.
  • Record-Triggered Flow: Automatically updates the Status field to the requested value and restricts approvals to Managing Directors.

In retrospect, it’s occurred to me that I could make several tweaks or incorporate alternative approaches.

  • In the screen flow, replace the lookup component with a Choice Lookup. This would require a Get Records element of all Managing Director users to populate the collection choice variable. However, if there’s a large number of Managing Directors, the picklist would be lengthy and it also wouldn’t show the titles of users, which the lookup component does.
  • In the screen flow, use a Get Records element on all Managing Director users prior to the initial screen and loop through the collection, adding the IDs to a text collection. Set the user input validation on the lookup component to check if the selected user is one of the IDs using the ‘Contains’ operator. This solution has merit but would require an error message that both captures the scenario of an ineligible user and if the user selects themselves. It could potentially slow down performance depending on the number of Managing Directors.

Your vote counts! Upvote these approval process related ideas on IdeaExchange.


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

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 […]

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 […]