The Hardcore Truth About Hardcoded Salesforce IDs
The Hardcore Truth About Hardcoded Salesforce IDs

The Hardcore Truth About Hardcoded Salesforce IDs

02/14/2022 by Mario Di Genio
In this post we’ll take a look at how you can avoid hardcoding IDs in automation in Salesforce.

Introduction

Hardcoding IDs is generally viewed as a bad practice. Sure, in the moment pasting an ID is the most direct way to make a reference to it and you want to focus more on getting the whole process to work than worrying about the minor details. You also want to keep it straightforward, instead of having a query or some complex step to retrieve the ID you want to set somewhere.

But nothing is forever, and when you hardcode the same ID in different places, if you ever need to change it to something else, then you would have to change every occurrence of such ID, wherever it may be. This can be very time consuming and also lead to new errors. For example, out of all the occurrences, maybe you forgot to fix one of them, or it was not changed correctly. This could cause the beginning of a long troubleshooting process you may not have the time for.

What if you were able to keep that ID centralized in one place, and then that place can be referenced from multiple places (formulas, process builders, flows, etc.)? Then if it ever needs to be changed, you would only have to do it once in the centralized place. The references would still be valid and would not need to be changed. Doesn’t that sound like the kind of maintenance you always dreamed of?

In this post we’ll show you different techniques to centralize IDs so that they can be referenced elsewhere, particularly automation such as workflow rules, process builders and flows. We’ll focus on Record Type IDs, but it could be any ID of any type of record that may need to be stored (a specific User ID, a public group or queue ID, a General Accounting Unit ID, etc.).

The Plan

How do we find all the occurrences of a Record Type ID?

  1. Download the entire org (configuration, code, everything).
  2. Search across the org for '012' (prefix of Record Type IDs).
  3. Make a spreadsheet with all the elements you find with hardcoded Record Type IDs.
  4. Choose the best way to store the IDs based on the analysis of what you have in your org
  5. Make the replacements in the automation.
  6. Document where IDs are stored, for what purpose and how to use them and pass it on to other System Administrators for future reference. This way anyone can reuse them for their own implementations, without falling into bad practices or repeating work. Knowledge and application are not worth unless you pass it on.

Analysis

These are the possible solutions to store the Record Type IDs for reference from automation and how each would work.

Custom Metadata Types (CMDT)

CMDT can be used in Process Builders and Flows, but cannot be used in workflow rules.

  • In CMDT you will have one record of the CMDT per Record Type ID you want to have available to reference in automation.
  • If you have some workflow rules with hardcoded Record Type IDs, this may be an issue (since workflow rules do not support CMDT) unless you migrate the workflow rules to a process builder or flow.
  • In a process builder you would choose the CMDT record in which the Record Type ID is stored (the CMDT record Name should follow a convention to identify which object and Record Type it is):

Hardcoded IDs Salesforce

In a flow you would have to retrieve the CMDT records you need (as any other Get Records node), which would add a query to your process.

Custom Settings

Custom Settings can be used in Workflow Rules, Process Builders (but only if the Custom Setting is of type Hierarchy Process Builder - Access to Custom Settings) and Flows.

  • Its usage is not as intuitive as CMDT; you would have to store each Record Type ID in a different field and then you would have one global Custom Setting record with all the Record Type IDs.

Hardcoded IDs Salesforce

Manage Records of a Custom Setting:Hardcoded IDs Salesforce

  • In a workflow rule (or field update action) you would choose to do the criteria with “formula evaluates to true” and establish the criteria comparing to the field in which the Record Type ID is stored of the global Custom Setting record (the field Name should follow a convention to identify which object and Record Type it is):

  • In a process builder you would choose to do the criteria with “Formula” and establish the criteria comparing to the field in which the Record Type ID is stored of the global Custom Setting record (the field Name should follow a convention to identify which object and Record Type it is):

  • In a flow you would choose the field in which the Record Type ID is stored of the global Custom Setting record (the field Name should follow a convention to identify which object and Record Type it is):

Custom Labels

Custom Labels can be used in Workflow Rules, Process Builders and Flows.

  • With Custom Labels you will have one Label per Record Type ID you want to have available to reference in automation.

  • In a workflow rule (or field update action) you would choose to do the criteria with “formula evaluates to true” and establish the criteria comparing to the Label in which the Record Type ID is stored (the Label Name should follow a convention to identify which object and Record Type it is):

  • In a process builder you would choose to do the criteria with “Formula” and establish the criteria comparing to the Label in which the Record Type ID is stored (the Label Name should follow a convention to identify which object and Record Type it is):

  • In a flow you would choose the Label in which the Record Type ID is stored (the Label Name should follow a convention to identify which object and Record Type it is):
    • Note: it takes quite a while for the form to load all the labels and filter as you type.

The following instructions are for the use of CMDT to replace hardcoded Record Type IDs in automation as an example, but since you may choose to go with Custom Labels or Custom Settings, additional instructions are interjected to work with Custom Labels or Custom Settings if needed.

CMDT with All Record Type IDs

We create the following “Master Record Type Table” CMDT to store all the Record Type IDs of all the objects that need to be used in automation:

Each record of the CMDT will store:

  • CMDT Label
  • Object API Name (for easy identification of what the ID is from)
  • Record Type API Name (for easy identification of what the ID is from)
  • Record Type ID

For example: if you need to use the Record Type https://mytest.lightning.force.com/lightning/setup/ObjectManager/Opportunity/RecordTypes/0123j000001Uni5AAC/view you will take the following data from it:

and create the CMDT record:

  1. Go to the Setup > Custom Metadata Types.
  2. Search for “Master Record Type Table” and click “Manage Records”.
  3. Click “New” button.
  4. Enter as Label the Object API Name (make sure you remove the “__c” if it's a custom object) - Record Type API Name.
    1. NOTE: This naming convention will make it easier for you to later find this specific record.
    2. NOTE: If you decide to use Custom Settings instead of CMDT, then you should use the same naming convention as this for the Field Name and then store the Record Type ID in the field of the master record of the Custom Setting.
    3. NOTE: If you decide to use Custom Labels instead of CMDT, then you should use the same naming convention as this for the Label Name and then store the Record Type ID in the Label Value.
  5. Enter Object API Name.
  6. Enter Record Type API Name.
  7. Enter Record Type ID.
  8. Save.

How to Use the CMDT

In any automation you can replace the hardcoded Record Type ID:

for a reference to the CMDT with the Record Type ID. For example, in a process builder:

  1. Change the Type from “ID” to “Formula”.
  2. Click “Build a Formula” button to set the value.
  3. Select “System Variables”:

  1. Select CustomMetadata:

  1. Select “Master Record Type Table”:

  1. Type the Object API Name so that the proper records of the CMDT display for selection (this is why the naming convention of the CMDT record is important, so that you can easily find them in this step):

  1. Select the record whose label has the Object API Name and Record Type API Name whose ID you want to use:

  1. Select Record Type ID field of that record:
  1. Click “Choose” button.
  2. The formula will populate with the path to the field:

  1. Click “Use This Formula” button.
  2. Now the hardcoded reference is replaced with the CMDT record.

The Takeaway

The ability to access Custom Settings, CMDTs, and Custom Labels via automation provides a whole set of possibilities to the functionality you can create declaratively. It can save time in the maintenance and troubleshooting of your solutions, as well as keeping information centralized and clean. Accessing IDs in automation is not ideal, but many times it’s just necessary, and accessing them does not necessarily mean that you have to fall into the bad practice of hardcoding. It’s an example of how important it is to use techniques, such as the ones presented in this post, to think of the maintenance of your solution before you start building it.

Resources

What do you think of the techniques to replace hardcoded IDs? Which one(s) have worked out best for you? Any other ways you know of centralizing IDs? Tell me all about it in the comments below, in the Salesforce Trailblazer Community, or tweet directly at me @mdigenioarkus. Subscribe to the Arkus newsletter here to get the top posts of the Arkus blog directly to your inbox.