Resolved: “Field is not writeable: Sobject__Share.RowCause”!

This post is about an issue that comes with Apex-managed sharing, i.e.

System.SObjectException: Field is not writeable: Sobject__Share.RowCause

I faced this problem recently and tried searching for this problem on force.com boards, but no solution was available. I only found a few open questions.

Upon debugging, I found that the cause of this error was an update of the RowCause field on “SObject__share” record. We are not changing RowCause, but accidentally copying back the same value.

So the fix is to never try to update RowCause field once the SObject__share record is created. If you need to change the RowCause field in SObject__share record, then delete it and create a new one.

Here is a minimalistic apex test case that reproduces this issue:

public static testmethod void testShareRecordUpdate() {
      // A custom standard user profile with required access on the custom object Specimen__c 
        Profile p = [SELECT Id FROM profile WHERE name='Cust Standard User'];
        // mock user for the same
        User mockUser = new User(alias = 'newUser', email='newuser@tgerm.com',
                  emailencodingkey='UTF-8', lastname='Testing', 
                  languagelocalekey='en_US', localesidkey='en_US', profileid = p.Id,
                  timezonesidkey='America/Los_Angeles', username='newuser@tgerm.com' + System.now().getTime());
        // Custom sobject with no special fields, just for sake of testing 
        Specimen__c specimen = new Specimen__c();
        
        system.runAs(mockUser) {
            insert specimen;
        }
        
        // Create an edit share
        Specimen__share readShare = new Specimen__share(
               AccessLevel = 'Edit',
               RowCause = Schema.Specimen__share.RowCause.Reason1__c,
               UserOrGroupId = Userinfo.getUserId(),
               ParentId = specimen.id
            );
        insert readShare;
        
        // One can assume some other flow, queries the same Share record and attemps the update
        Specimen__share editShare = [Select AccessLevel,RowCause from Specimen__share 
                                        where UserOrGroupId = :Userinfo.getUserId() 
                                        AND ParentId =:specimen.id 
                                        AND RowCause = :Schema.Specimen__share.RowCause.Reason1__c                         
                                        ];
        
        // Comment this line to get rid of 
        // this error : "Field is not writeable: Specimen__Share.RowCause"
        editShare.RowCause = Schema.Specimen__share.RowCause.Reason1__c;
        editShare.AccessLevel = 'Read';
        update editShare;
    }

I would say this error should be something else, as the field “RowCause” is writable on record creation but not updateable.

Abhinav Gupta

First Indian Salesforce MVP, rewarded Eight times in a row, has been blogging about Salesforce, Cloud, AI, & Web3 since 2011. Founded 1st Salesforce Dreamin event in India, called “Jaipur Dev Fest”. A seasoned speaker at Dreamforce, Dreamin events, & local meets. Author of many popular GitHub repos featured in official Salesforce blogs, newsletters, and books.

https://abhinav.fyi
Previous
Previous

Force.com Developer Console Navigation Trick

Next
Next

Yet another Apex Trigger Template !