The Salesforce documentation on Triggers and Order of Execution suggests that criteria-based sharing rules are the third to last thing to run. I'm wondering if they really run only once per execution context and if that is documented anywhere. If you insert a record that the running user has access to only as a result of criteria-based sharing rules (and the code is running with sharing), access to the record is not available in the rest of the class.

Here is a simplified example I came up with. Hotels are private. All internal users have access only via a criteria-based sharing rule, and the rule is simple, Name != null, giving them access to all records. When a non-admin user runs the following code, the assert throws an error:

public with sharing class CreateHotel {
   @InvocableMethod(Label='Create Hotel Test')
   public static void insertRecord(List<String> hotelNames) {
       Id newOwnerId = [SELECT Id FROM User WHERE Profile.Name = 'System Administrator' AND IsActive = true LIMIT 1].Id; 
       List<Hotel__c> hotels = new List<Hotel__c>(); 
       for(String hotelName:hotelNames){
               new Hotel__c(
                   Name = hotelName, 
                   OwnerId = newOwnerId
       insert hotels; 
       List<Hotel__c> foundHotels = [SELECT Id FROM Hotel__c WHERE Id IN :hotels]; 
       System.assertEquals(hotelNames.size(), foundHotels.size(), 'Not all the new hotels were found'); 

When 'with sharing' is changed to 'without sharing', then no error is thrown. Why does sharing happen only after all code is run, or am I missing something?

  • Something to note using system.assert... methods in apex is not recommended, it is designed for Test Methods to test criteria. It is not scalable or as maintainable, yes quick but has other downsides. use "public class MyException extends Exception {}" extra line in your class instead, with "throw new MyException(..." May 4, 2022 at 5:32
  • Thanks. The assert was just for creating a quick demo of the problem, but good to keep in mind.
    – kare
    May 5, 2022 at 16:10

1 Answer 1


The Criteria based sharing rules run synchronously as documented but the actual share records are created asynchronously.

This is not publicly documented yet but you can easily see in transaction logs that records are not created immediately.

You can query the share records as well in the transaction and you will not see any records which proves that the share records are created asynchronously.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .