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.