Protecting fields used in integrations from deletion

h/t to a number of folks on this one, esp Luke Cushanick who shared the idea for this.

Marking fields used in integrations in some way, to prevent them from being deleted, might be useful. Even more useful might be to document which integrations use them, and how.

After some discussion, this can be done using a custom metadata type fairly easily. No code!

Create custom metadata type, lets name it “Integration Field”

Then add 2 fields to the metadata type to track where this is used

Integration name : type = text
Description : type = text area

Now and the magic : create two metadata relationship fields, in order

Object Name : type = metadata relationship, related to entity definition
Field Name : type = metadata relationship, related to field definition


Screenshot of “Field Name” - first set “related to” = field definition, then set the controlling field to “Object Name”



when you are all done, the fields on your custom metadata type should look like this - see that the controlling field is set on Field Name.


Now, click the ‘Manage Integration Fields’ button at the top of the page and then click ‘new’ to add a record to the metadata type.

Add the basic info, then select any object, and select a field on that object
(preferably a custom field, since you can then try deleting it and watch this block you), and click save.

And presto - with the magic of the metadata relationship fields, you now have a dependent picklist with all object names and all field names in your instance at your disposal.


Now go to setup, and go to your custom object, and try to delete the custom field you just mapped. And you shall be blocked!


A few notes:
Custom metadata relationship fields cannot reference Activity (tasks or events) or User fields. (h/t to Ch. Szandor Knapp reference here

There is a limit of 10 million characters of custom metadata in your org. So write the novella about your integration architecture elsewhere, and link to it from here.

You may want to use the Label of the MDT record to record the integration that the field is used in (instead of a separate integration name field) as the Label is what is displayed in the error message on delete.

Unfortunately this tooling will not prevent admins from modifying the field in ways that can break your integration, nor will it alert you if the field is modified. However, you will have one place you can view all your fields used in various integrations. No reports either on MDTs, so, it is what it is…but a nice declarative way to protect fields from deletion, and do a little documentation to boot.

To ‘flag’ standard compound fields (like address) I believe you would need to add a metadata relationship to entity particle instead of (or in addition to) field definition, but almost all fields should show up as field definition (from what i understand)

If the field is referenced in validation rules, workflow rules, flows, etc - those issues will be displayed on delete and the MDT will not surface. You may have noticed that the ‘blocked’ example screenshot was a different field from the one I initially flagged. Turns out that Web_Profile_c.Twitter_c is used in validation rules and a flow, and therefore the metadata type reference was not surfaced. Screenshot below.



Now read this

Keep your (users) API access in check (part 1)

There are tons of amazing applications out there that connect to Salesforce - heroku apps like the perm comparator, salesforce plugins for excel, chrome extensions, and on and on. These tools allow users and admins to do amazing things,... Continue →