Long story short, I want to share a Contact record with a User given certain criteria in an Apex trigger. One of the things I want to check is if the User is active because creating a ContactShare object pointing to an inactive User would throw an error. So I do the following in my code:

    for (Contact c : Contacts)
        system.debug('IsActive = ' + c.pse__Salesforce_User__r.isActive);
        //If this Contact's email also belongs to a User, AND that User is 
        //their Salesforce User Lookup, share this contact with the User.
        if(c.Email != null && userEmailMap.containsKey(c.Email) && (c.pse__Salesforce_User__c == userEmailMap.get(c.Email).ID) && (c.pse__Salesforce_User__r.isActive == TRUE)){

            ContactShare cs = new ContactShare(ContactID = c.ID, 
                                              UserorGroupId = userEmailMap.get(c.Email).ID, 
                                              ContactAccessLevel ='Read');


pse__Salesforce_User__r is a lookup to a User on the Contact. I was testing this code on a User that I am 100% sure is Active, (the 'Active' Checkbox is checked) so you'll have to take my word on that part. But that debug message shows IsActive = false. I have this issue on any User I try this with. Why is that IsActive field not accurate? Am I using the wrong field?


  • 1
    Where have you queried for the isActive field? Triggers don't by default include values for parent records. – Nick Cook Aug 21 '19 at 23:36

It appears that you've put Trigger.new into the Contacts variable. This is problematic, because relationship fields are not populated by default, and as it so happens, Boolean values default to a false value if you try to reference them without querying them. You can easily verify this behavior with this simple Execute Anonymous Script:

Contact c = new Contact();
System.debug(c.Owner.IsActive); // = false

The solution is the Aggregate-Query-Update pattern. Basically, you need to grab the records first:

// Aggregate Id values
Map<Id, User> users = new Map<Id, User>();
for(Contact c: Contacts) {
  users.put(c.pse__Salesforce_User__c, null);
// Query for parent records
users.putAll([SELECT Email, IsActive FROM User WHERE Id = :users.keySet()]);
// Do updates
ContactShare[] contactsToManuallyShare = new ContactShare[0];
for(Contact c: Contacts) {
  User u = users.get(c.pse__Salesforce_User__c);
  if(u != null && c.Email == u.Email && u.IsActive) {
      new ContactShare(ContactId = c.Id, UserOrGroupId = u.Id, ContactAccessLevel = 'Read')
insert contactsToManuallyShare;
  • Thank you, after requerying within my method directly the value was correct. I was totally unaware that was an issue. – user72219 Aug 22 '19 at 14:15

can you give a try with this

if(c.Email != null && userEmailMap.containsKey(c.Email) && (c.pse__Salesforce_User__c == userEmailMap.get(c.Email).ID) && (c.pse__Salesforce_User__r.isActive))

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.