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.