While working on my Email Invalidation Tool, I ran into Salesforce truncating Custom Metadata text fields at 512 characters. I struggled at first to understand why the static methods – my goto with Custom Metadata – were resulting in broken records. Turns out the solution is simple – use SOQL.
The Problem: Salesforce Truncates Custom Metadata Text Fields
When loading Salesforce Custom Metadata records using the static methods getInstance() or getAll() long strings are truncated at 511 characters (probably 512 bytes actually, I am not sure what happens if you have multi-byte characters in the string character 512 is probably a null terminator).
My Use Case, and Reproduction
One of the features I wanted to add to my email invalidation tool was auto-detection of email fields. That’s turned out to be a whole complicated process that I’m still finishing as of this post date. Part of the solution I am using is to create a custom metadata object to store a list of possible fields. For a variety of unimportant reasons I elected to store that information as a JSON string. So I created a long textarea field maxed out at 131,072 characters. Everything went fine at first: the process scans the objects and drops the results into the metadata record. When I looked at the records in the UI or after downloading to a file it looked just as I expected. But when I started to load the records again I got JSON parser errors because the value had been truncated to 511 characters.
Preventing Salesforce Custom Metadata Text Truncation
The answer is to use SOQL. I typically use the static methods when working with Custom Metadata to reduce the number of SOQL queries in my code – but in this case that doesn’t work. To reliably get all the data in long text fields you have to use SOQL.
This approach consistently gives you a truncated values:
Email_Invalidator_Cache__mdt cacheRecord = Email_Invalidator_Cache__mdt.getInstance(
'Field_Scan'
);
But using a simple SOQL statement to load the same record works just fine:
Email_Invalidator_Cache__mdt cacheRecord = [
SELECT QualifiedApiName, Cached_Value__c, SystemModstamp
FROM Email_Invalidator_Cache__mdt
WHERE DeveloperName = 'Field_Scan'
];
Ask Salesforce to Fix This
There is an idea open requesting a fix to this issue. Please up vote.
Special Thanks
Thank you to Robbie Duncan for helping me out on Ohana Slack with this one.