I'm struggling with the functionality of pageReference.getContent() inside my batch.

When running the following batch in dev, works like a charm.

When running it in a package, getContent returns an empty string.

I couldn't point the issue.

public without sharing class BatchSetCustomObjectTypeIds implements Database.Batchable<sObject>, Database.AllowsCallouts {

  public Database.QueryLocator start(Database.BatchableContext bc) {
    String query = 'SELECT Id from Account limit 1';
    return Database.getQueryLocator(query);

  public void execute(Database.BatchableContext bc, List<Account> scope) {
    try {
      final String CUSTOM_OBJECT_PAGE_URL = '/p/setup/custent/CustomObjectsPage?setupid=CustomObjects';
      Pagereference pr = new PageReference(CUSTOM_OBJECT_PAGE_URL);
      String htmlContent = pr.getContent().toString();
      Logger.log('result from getContent ' + htmlContent);
    catch (Exception ex) {
    finally {
      Logger.log('End BatchSetCustomObjectTypeIds');

  public void finish(Database.BatchableContext bc) {
  • You're running this from a InstallHandler interface class?
    – sfdcfox
    Dec 25 '17 at 13:53
  • Yes, Exactly.. Is that not allowed? @sfdcfox Dec 25 '17 at 14:25
  • 1
    the documentation says that it doesn't get a Session ID. I think that the batch may also not get a Session ID. I don't have any easy way to prove this at the moment though. You might need to create a Configuration Visualforce page so the administrators can run this after installing.
    – sfdcfox
    Dec 25 '17 at 14:38
  • @sfdcfox , Thank you very much for your insights. May I ask how can I get the customObjectTypeId? (As I tried to parse the html and get it from there). As It seems complicated this way, is there another way to get the customObjectTypeId? Thanks again. Dec 25 '17 at 14:54
  • what do you need the CustomObject ID for, exactly? Perhaps you need to take a step back and start with asking about the original problem. Please read more about the x-y problem, since it seems relevant here.
    – sfdcfox
    Dec 25 '17 at 15:33

Agreed with @sfdcfox about the "x-y problem". Please explain your use case more?

But if the CustomObject ID is what you really need though, there are better ways to do it than screen-scraping.

For custom objects you can find this ID as DurableId in EntityDefinition, so for example:

SELECT DeveloperName, DurableId FROM EntityDefinition 
WHERE DeveloperName = 'MyCustomObject__c'

Note that this table returns also standard objects and entities representing feeds, sharing etc. So you'd have to filter it to get only custom.

Also note regarding DurableId:

Unique identifier for the field. Always retrieve this value before using it, as the value isn’t guaranteed to stay the same from one release to the next.

So unless you have a very strong need to be querying these all in a batch on install, and only on install, you're probably better to query this as-needed when working with the sObject(s) in question.

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.