3

I have a class in charge of creating local translations within a custom label, this class is responsible for going into the metadata and creating it. The code is as follows:

global with sharing class LocalTranslations_MDT {

  global static void addLocalTranslations(String customLabelName, String valueTranslation, String theme, String sessionId)
  {
      String translationName = UserInfo.getLanguage();
      MetadataService.MetadataPort service = createService(theme, sessionId);
      MetadataService.Translations translationField =
          (MetadataService.Translations) service.readMetadata('Translations',
              new String[] { translationName }).getRecords()[0];

      if(translationField.customLabels == null)
          translationField.customLabels = new MetadataService.CustomLabelTranslation[]{};
      MetadataService.CustomLabelTranslation clt = new MetadataService.CustomLabelTranslation();
      clt.label    = valueTranslation;
      clt.name     = customLabelName;

      translationField.customLabels.add(clt);

      handleSaveResults(
          service.updateMetadata(
              new MetadataService.Metadata[] { translationField })[0]);
  }

  public class MetadataServiceException extends Exception { }
  
  public static MetadataService.MetadataPort createService(String theme, String sessionId)
  {
    MetadataService.MetadataPort service = new MetadataService.MetadataPort();
    service.SessionHeader = new MetadataService.SessionHeader_element();
    if (theme == 'Theme4d' || theme == 'Theme4t')
      service.SessionHeader.sessionId = Utils.getSessionIdFromVFPage(Page.SessionId);
    else 
      service.SessionHeader.sessionId = sessionId;
    return service;
  }

  public static void handleSaveResults(MetadataService.SaveResult saveResult)
  {
    // Nothing to see?
    if(saveResult==null || saveResult.success)
      return;
    // Construct error message and throw an exception
    if(saveResult.errors!=null)
    { 
      List<String> messages = new List<String>();
      messages.add(
          (saveResult.errors.size()==1 ? 'Error ' : 'Errors ') +
              'occured processing component ' + saveResult.fullName + '.');
      for(MetadataService.Error error : saveResult.errors)
          messages.add(
              error.message + ' (' + error.statusCode + ').' +
              ( error.fields!=null && error.fields.size()>0 ?
                  ' Fields ' + String.join(error.fields, ',') + '.' : '' ) );
      if(messages.size()>0){
        throw new MetadataServiceException(String.join(messages, ' '));
      }
    }
    if(!saveResult.success)
      throw new MetadataServiceException('Request failed with no specified error.');
  }
}

When I invoke the method inside a scratch everything works correctly, but when I invoke it inside Packaging Org I get the following error:

Auctifera.LocalTranslations_MDT.MetadataServiceException: Error occured processing component en_US. In field: name - no ReportType named screen_flows_prebuilt_crt found (INVALID_CROSS_REFERENCE_KEY).

The way to invoke the method is the following:

LocalTranslations_MDT.addLocalTranslations('Only_test_local_translation','Test message' ,UserInfo.getUiTheme(), UserInfo.getSessionId());

Metadata service:

https://github.com/financialforcedev/apex-mdapi/blob/master/apex-mdapi/src/classes/MetadataService.cls

  • 1
    Works on Scratch but not on packaging usually means issue with namespace prefix? Maybe try adding namespace to the custom label name? – Raul Oct 7 at 22:48
1

Did a quick test on my DEV org and tried to add a translation to packaged custom label with the amazing Apex Wrapper Salesforce Metadata API.

Adding a namespace to custom label name worked for me:

MetadataService.CustomLabelTranslation clt = 
    new MetadataService.CustomLabelTranslation();
clt.label    = 'Some text';
// replace namespace prefix below with yours-
clt.name     = 'NamespacePrefix__CustomLabelName';
translationField.customLabels.add(clt);

| improve this answer | |
  • We used mdapi commands along with packages, to mitigate this issue – Ysr Shk Oct 8 at 10:38
  • I made the change suggested by Raul of adding the prefix but the same thing happens, at the moment of testing it in the Scratch it works correctly but in the Packaging Org it fails with the same error: Auctifera.LocalTranslations_MDT.MetadataServiceException: Error occurred processing component en_US. In field: name - no ReportType named screen_flows_prebuilt_crt found (INVALID_CROSS_REFERENCE_KEY). – Juan Cubillos Oct 8 at 14:15
  • Update: We were able to fix the problem by deleting the recordType: screen_flows_prebuilt_crt – Juan Cubillos Oct 8 at 14:18
  • @Juan not sure how deleting record type resolves issue with custom label translation creation via metadata service. Kindly elaborate? – Raul Oct 8 at 16:06
  • @Ysk Shk, that ia very interesting way to solve namespace problem, do you have maybe have any references or blog post or bit more details to learn more about it. – Raul Oct 8 at 16:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.