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.

Summarize ChatGPT Claude Grok Perplexity Copilot
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

Salesforce Email Services: Where is the "Delete" button?

Next
Next

Yet Another Apex Trigger Template!