function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Nikhil Garg 17Nikhil Garg 17 

Metadata Retrieval

Hi Team,

I'm retrieving metadata of specific components and here I'm retrieving metadata of type "Custom Object".
It's reading metadata of some objects but after certain objects it throws error like "Web service callout failed: Unable to find apex schema info at 13476". I need to fetch metadata of every object in my org.
Here is my code

public class MetadataRetriever {
    
    Public static Map<String, Blob> xmlBlobData {get;set;}
    
    Public static List<Map<String,List<Map<String, object>>>> asyncVariable=new List<Map<String,List<Map<String, object>>>>();
    
    @RemoteAction
    public static Map<String,List<Map<String, object>>> retrieveAllMetadata() {
        
        Map<String,List<Map<String, object>>> MetadataMapByType = new Map<String,List<Map<String, object>>>();
        Map<String, List<String>> metadataByType = new Map<String, List<String>>();
       
        try {
            
            MetadataService.MetadataPort service = new MetadataService.MetadataPort();
            service.SessionHeader = new MetadataService.SessionHeader_element();
            service.SessionHeader.sessionId = UserInfo.getSessionId();
            
            
           // List<String> MetadataNames=new List<String>{'StaticResource','NamedCredential','CustomTab'};
            List<String> MetadataNames=new List<String>{'CustomObject'};
            List<MetadataService.ListMetadataQuery> queries=new List<MetadataService.ListMetadataQuery>();
            
            for(integer i=0;i<MetadataNames.size();i++)
                {
                        MetadataService.ListMetadataQuery query = new MetadataService.ListMetadataQuery();
                        query.type_x = MetadataNames[i]; 
                        query.folder = MetadataNames[i];
                        queries.add(query);
                }
            
            List<List<MetadataService.ListMetadataQuery>> batches = new List<List<MetadataService.ListMetadataQuery>>();
            
            for(integer i=0;i<queries.size();i +=3){
                List<MetadataService.ListMetadataQuery> Batch = new List<MetadataService.ListMetadataQuery>();
                    for(integer j=i;j<i+3;j++){
                        if(j<queries.size()){
                            batch.add(queries[j]);
                        }
                    }
                    batches.add(batch);
                }
                
            system.debug('batches>>>>>>>>>>');
            system.debug(batches);
                
            
            
       for(MetadataService.ListMetadataQuery[] batch:batches){
           
         //  AsyncProcessing.processMetadata(JSON.serialize(batch));
           
           MetadataService.FileProperties[] fileProperties2 = service.listMetadata(batch,(Double) 58.0);
           
          for (MetadataService.FileProperties fileProperty : fileProperties2) {
              
                String componentType = fileProperty.type_x;
                String componentName = fileProperty.fullName;
                  system.debug('componentName>>>>>');
                 system.debug(componentName);
              
                if (!metadataByType.containsKey(componentType)) {
                    metadataByType.put(componentType, new List<String>());
                }
                metadataByType.get(componentType).add(fileProperty.fullName);
              
                MetadataService.Metadata metadata = service.readMetadata(componentType, new List<String>{componentName}).getRecords()[0];
                
                string jsonString=JSON.serialize(metadata);
                Blob xmlBlob = Blob.valueOf(jsonString);
                
                Map<String, Object> metadataMap = new Map<String, Object>();
                metadataMap.put('componentName', componentName);
                metadataMap.put('xmlBlob', EncodingUtil.base64Encode(xmlBlob));
              
                  if(MetadataMapByType.containsKey(componentType)){
                      List<Map<String, object>> tempMetadata =new List<Map<String, object>>();
                      tempMetadata = MetadataMapByType.get(componentType);
                      tempMetadata.add(metadataMap);
                      MetadataMapByType.put(componentType, tempMetadata);
                  }else{
                      List<Map<String, object>> tempMetadata = new List<Map<String, object>>{metadataMap};
                      MetadataMapByType.put(componentType, tempMetadata);                      
                  }

            }
       /* system.debug('metadataByType>>>>>>');
        system.debug(metadataByType);*/
           
          
        }
        }catch (Exception e) {
            // Handle exception
            System.debug('Error: ' + e.getMessage()+' at '+e.getLineNumber());
        }
        
       system.debug('Metadata component>>>>>>>>>>>>>>>>>');
       system.debug(metadataByType);
        system.debug('size<<<<<<<<<<<<<<<<<<<<<<<<');
       // system.debug(metadataByType.size());
       system.debug('data to vf page>>>>>>>>');
       system.debug(MetadataMapByType);
        system.debug('async variable');
        system.debug(asyncVariable);
       return MetadataMapByType;

    }
  
}

 

Kindly help, Need to do this on urgent basis.

Thanks & Regards 
Nikhil Garg

SubratSubrat (Salesforce Developers) 
Hello ,

The error you are encountering, "Web service callout failed: Unable to find apex schema info at 13476," indicates that there is a problem with your callouts to the Metadata API. This error is thrown when the Apex code is unable to parse the response from the Metadata API properly.

One possible reason for this error is that the response size from the Metadata API is exceeding the maximum heap size allowed for a single Apex transaction, which is 6 MB for synchronous and 12 MB for asynchronous transactions. When you retrieve metadata for a large number of Custom Objects, the response size can grow significantly, leading to this error.

To overcome this issue, you can try the following:

Reduce the batch size: Instead of making bulk callouts for multiple objects at once, try reducing the batch size to retrieve metadata for a smaller number of objects in each callout.

Implement pagination: Use the MetadataService with a pagination approach to retrieve the metadata in smaller chunks. You can retrieve metadata for a certain number of Custom Objects at a time and then proceed to the next batch.

Check for nested metadata: If you are retrieving related metadata (child components) along with the Custom Object metadata, ensure that the response size doesn't grow too large due to nested metadata.

Limit the number of properties: In the MetadataService.FileProperties[] fileProperties2 loop, consider reducing the number of properties you retrieve for each component to minimize the response size.

Check for any large XML responses: If any of the components have particularly large XML responses, it can contribute to the issue. Consider reviewing the XML responses to identify any large components and handle them differently.

Batch the overall process: Instead of retrieving metadata for all Custom Objects in one go, implement a batch process that runs multiple times to retrieve metadata for different sets of objects.

By implementing the above strategies, you can reduce the response size and avoid hitting the heap size limit, thus resolving the "Web service callout failed: Unable to find apex schema info at 13476" error. 

Hope this helps !
Thank you.
Nikhil Garg 17Nikhil Garg 17
Hi subrat

Thanks for your response, I like the approach you suggested.
But I have one question If I'll break my apex transaction in batches(async), and if I need to retrun some data back to my apex class after process of every batch , do any method of async return data or there is any other appoach that I should follow