I am trying to add permissions to Account fields using Metadata Api. I am receiving the error " Invalid field permission field name Account field Account.billingstatecode" and the permission set is not being created. How do I resolve this

Thank you

public class AssignReadPermissionsBatch implements Database.Batchable<sObject>,Database.AllowsCallouts {
    public Database.QueryLocator start(Database.BatchableContext bc) {
        // collect the batches of records or objects to be passed to execute
       // String query='SELECT SObjectType From ObjectPermissions';
         String query = 'Select Name from DatalakeObjects__c';
         return Database.getQueryLocator(query);
    public void execute(Database.BatchableContext bc, List<DatalakeObjects__c> records){
        // process each batch of records
        List<MetadataService.PermissionSetObjectPermissions> objPermissions = new List<MetadataService.PermissionSetObjectPermissions>();
        List<MetadataService.PermissionSetFieldPermissions> fldPermissions = new List<MetadataService.PermissionSetFieldPermissions>();
        for (DatalakeObjects__c obj:records){
            //DescribeSObjectResult objDef = obj.getDescribe();
            MetadataService.PermissionSetObjectPermissions objPrmsn = new MetadataService.PermissionSetObjectPermissions();
            objPrmsn.object_x = obj.Name;
           // objPrmsn.allowRead = true;
            objPrmsn.allowCreate = false;
            objPrmsn.allowDelete = false;
            objPrmsn.allowEdit = false;
            objPrmsn.allowRead = true;
            objPrmsn.viewAllRecords = true;
            objPrmsn.modifyAllRecords = false;
            //Map<String, SObjectField> fields = objDef.fields.getMap();
            //Set<String> fieldSet = fields.keySet();
            //List <String> fieldLst = Utilities.getFields(obj.Name);
            SObjectType objToken = Schema.getGlobalDescribe().get(obj.Name);
            DescribeSObjectResult objDef = objToken.getDescribe();
            Map<String, SObjectField> fields = objDef.fields.getMap(); 
            Set<String> fieldSet = fields.keySet();

            for(String fldName:fieldSet){
                SObjectField fieldToken = fields.get(fldName);
                DescribeFieldResult selectedField = fieldToken.getDescribe();
                if(selectedField.isPermissionable() && selectedField.isAccessible()){
                MetadataService.PermissionSetFieldPermissions fldPrmsn = new MetadataService.PermissionSetFieldPermissions();
                //fldPrmsn.field = selectedField.getName();
                fldPrmsn.field = obj.Name+'.'+fldName;
                fldPrmsn.readable = true;
                fldPrmsn.editable = false;
                // fieldList.add(selectedField.getName());
        }//end of upper for
        MetadataService.PermissionSet ps = new MetadataService.PermissionSet();
        ps.fullName = 'Assign_ReadOnly';
        ps.label = 'AssignReadOnly_3';
        ps.objectPermissions = objPermissions;
        ps.fieldPermissions = fldPermissions;
        ps.hasActivationRequired = false;
        MetadataService.MetadataPort service = new MetadataService.MetadataPort();
        service.timeout_x = 60000;
        service.SessionHeader = new MetadataService.SessionHeader_element();
        service.SessionHeader.sessionId = UserInfo.getSessionId();
         MetadataService.Metadata[] mtDataList = new List<MetadataService.Metadata>();
        List<MetadataService.SaveResult> results;
            results = service.createMetadata(mtDataList);
        }else {
            results = new List<MetadataService.SaveResult>();
            results[0].success = false;
            MetadataService.Error err = new MetadataService.Error();
            err.message = 'test';
            List<MetadataService.Error> errList = new List<MetadataService.Error>{err};
                results[0].errors = errList;
        for(MetadataService.SaveResult res: results){
            if(res.errors != null){
                for(MetadataService.Error err:res.errors){
                    System.debug('err mess '+err.message);
    public void finish(Database.BatchableContext bc){
        // execute any post-processing operations
  • 1
    Billingstatecode is a part of billingstate, could you try to grant access to that field instead? – Jeferson Chaves Apr 17 at 14:10
  • No, I am looping through all the fields from Account using schema programming, the system is taking Billingstatecode only – vara Apr 17 at 15:19
  • Fair enough but I don't think you can restrict billingstatecode you will have to restrict billingstate. – Jeferson Chaves Apr 17 at 16:03
  • 2
    Have you enabled state and country picklist in your org, as these field will be available only if the state and country picklists are activated – sumit bhatt Apr 17 at 16:34
  • @jaferson How do I restrict billing state – vara Apr 17 at 16:42

You could use a map and check for any overrides to the schema field names.

Something like this:

Map<String,String> fieldNameOverride = new Map<String,String>{

//from your previous question
for(String fldName:fieldLst){

    //if there is an override, use that.
    fldName = fieldNameOverride.containsKey(fldName) ? fieldNameOverride.get(fldName) : fldName;
    MetadataService.PermissionSetFieldPermissions fldPrmsn = new MetadataService.PermissionSetFieldPermissions();
    fldPrmsn.field = fldName;
    fldPrmsn.readable = true;
    fldPrmsn.editable = false;

This way, if you encounter anymore overrides, just add them to the fieldNameOverride Map.

Also, you might need to tweak this to put it in the format ObjectApiName.FieldApiName

  • I have pasted my code, could you please let me know where exactly the changes can be made – vara Apr 18 at 4:30

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.