Unable to Share Record Access Through Apex Sharing Rules?
Question:
Why is record sharing using Apex sharing rules failing with the error System.QueryException: List has no rows for assignment to SObject
when trying to share high-priority project records from the Project__c
object with a public group? The Apex sharing rule uses a custom sharing reason, Project_Sharing_Rule
, and the code executes in an after
insert
or after updat
e
trigger. Below is the trigger and class used:

Trigger Code:
trigger ProjectSharingTrigger on Project__c (after insert, after update) {
if (Trigger.isInsert || Trigger.isUpdate) {
ProjectSharingHelper.shareHighPriorityProjects(Trigger.new);
}
}
Helper Class Code:
public class ProjectSharingHelper {
public static void shareHighPriorityProjects(List<Project__c> projects) {
List<Project__Share> sharesToInsert = new List<Project__Share>();
Id groupId = [SELECT Id FROM Group WHERE Name = 'Project_management_team' LIMIT 1].Id;
for (Project__c proj : projects) {
if (proj.Priority__c == 'High') {
Project__Share projectShare = new Project__Share();
projectShare.ParentId = proj.Id;
projectShare.UserOrGroupId = groupId;
projectShare.AccessLevel = 'Read';
projectShare.RowCause = Schema.Project__Share.RowCause.Project_Sharing_Rule__c;
sharesToInsert.add(projectShare);
}
}
if (!sharesToInsert.isEmpty()) {
try {
insert sharesToInsert;
System.debug('High-priority project shared with team successfully.');
} catch (DMLException e){
System.debug('Error sharing projects: ' + e.getMessage());
}
}
}
}
When a new project record with a priority of “High” is created, the following error occurs:System.QueryException: List has no rows for assignment to SObject
.
Answer:
The inability to share record access through Apex sharing rules often results from issues like incorrect SOQL queries or missing data, such as Group IDs. To resolve this, ensure proper query handling, check for empty results, and implement defensive coding practices. Understanding object relationships and access levels, along with using bulk-safe logic, is crucial for effective record sharing and maintaining scalability. The error indicates that the query attempting to fetch the public group ID in the shareHighPriorityProjects
method is returning no results.
CRS Info Solutions offers expert-led Salesforce Online Training with real-world projects, certification guidance, and career-focused support.
The issue lies in the query:
Id groupId = [SELECT Id FROM Group WHERE Name = 'Project_management_team' LIMIT 1].Id;
Explanation : The code snippet queries the Salesforce database for a specific record in the Group
object where the Name
field is equal to ‘Project_management_team’. It uses a SOQL (Salesforce Object Query Language) query to search for the record, and the LIMIT 1
ensures that only the first matching record is returned, preventing any errors if there are multiple records with the same name. The SELECT Id
part of the query retrieves only the Id
field of the Group
object. After the query is executed, the Id
of the matching group is stored in the groupId
variable.
Key Considerations
The code may throw a System.QueryException
if the query doesn’t find any records, as it directly assigns the result to an Id
without checking for existence. To avoid this, the query result should be stored in a list and checked for null or empty before accessing the Id
. This ensures safer querying and prevents runtime errors when no records are found.
For example:
Group groupRecord = [SELECT Id FROM Group WHERE Name = 'Project_management_team' LIMIT 1];
if (groupRecord != null) {
Id groupId = groupRecord.Id;
} else {
System.debug('No group found with the name "Project_management_team".');
}
Explanation : The code queries the Group
object to find a record with the name “Project_management_team” and stores its Id
if found. If no such group exists, it logs a debug message indicating the absence of the group.
Solution 1: Validate the Public Group’s Existence
Ensure that the public group named Project_management_team exists in your Salesforce org. Check the spelling, capitalization, and spaces in the group name. If the group doesn’t exist, create it in Setup > Public Groups and ensure it matches the query’s criteria.
Solution 2: Use a Safer Query Approach
Instead of assigning the query result directly to an ID variable, handle the case where no records are found. Update the code as follows:
public static void shareHighPriorityProjects(List<Project__c> projects) {
List<Project__Share> sharesToInsert = new List<Project__Share>();
Group group = [SELECT Id FROM Group WHERE Name = 'Project_management_team' LIMIT 1];
if (group == null) {
System.debug('Group "Project_management_team" does not exist.');
return; // Exit the method if the group is missing
}
Id groupId = group.Id;
for (Project__c proj : projects) {
if (proj.Priority__c == 'High') {
Project__Share projectShare = new Project__Share();
projectShare.ParentId = proj.Id;
projectShare.UserOrGroupId = groupId;
projectShare.AccessLevel = 'Read';
projectShare.RowCause = Schema.Project__Share.RowCause.Project_Sharing_Rule__c;
sharesToInsert.add(projectShare);
}
}
if (!sharesToInsert.isEmpty()) {
try {
insert sharesToInsert;
System.debug('High-priority project shared with team successfully.');
} catch (DMLException e){
System.debug('Error sharing projects: ' + e.getMessage());
}
}
}
Explanation : The shareHighPriorityProjects
method shares high-priority projects with a specific group, ‘Project_management_team’, by creating Project__Share
records. It first checks if the group exists, retrieves its ID, and then iterates through the provided projects, adding shares for those marked as ‘High’ priority. The method then attempts to insert the share records and handles any errors during the DML operation.
Solution 3: Query Optimization and Logging
If the group exists but the query still fails, ensure that the group is accessible to the running user’s profile or permission set. Debugging statements can help verify the issue:
public static void shareHighPriorityProjects(List<Project__c> projects) {
List<Project__Share> sharesToInsert = new List<Project__Share>();
Group[] groups = [SELECT Id FROM Group WHERE Name = 'Project_management_team' LIMIT 1];
if (groups.isEmpty()) {
System.debug('No group found with the name "Project_management_team".');
return;
}
Id groupId = groups[0].Id;
// Remaining logic
}
Explanation : The code defines a method shareHighPriorityProjects
that shares a list of Project__c
records with a specific group, “Project_management_team.” It first queries the Group
object to find the group with the name “Project_management_team” and retrieves its Id
. If the group is not found, it logs a message and exits; otherwise, it proceeds with further logic to share the projects.
Summing Up
The inability to share record access through Apex sharing rules often arises from issues like mishandling SOQL queries, leading to errors such as “List has no rows.” Implementing defensive coding practices, such as checking for empty query results and logging, can prevent these errors and improve debugging. Understanding the relationships between objects, sharing reasons, and access levels is key to successful sharing. By focusing on bulk-safe logic and validating preconditions, developers can create scalable and maintainable record sharing functionality.
Salesforce Training in Bangalore: Build Your Career with Confidence
Discover the path to Salesforce excellence with our industry-focused training program in Bangalore. Designed to help you master the Salesforce ecosystem, our program offers expert certification guidance, in-depth interview preparation, and comprehensive modules tailored for Admin, Developer, and AI tracks. Our hands-on approach ensures you gain real-world skills to stand out in the competitive job market.
With detailed class notes, practical learning opportunities, Salesforce training in Bangalore and personalized mentorship, we prepare you to tackle industry challenges with confidence. Don’t miss the chance to elevate your career—join our free demo class today and experience the difference that quality training makes!
Related Posts :