I am new to writing Apex Triggers. I wrote this trigger by referring few examples, but now i end-up with ContactAccessLevel field is not writable Error.

Use Case: In contact object, I have a field called xrx_mf_crm__Region_1__c. If the value of this field matches the public groups name, then the record should be shared with that public group with read/write access.

trigger ContactShareByRegion1 on Contact (After Insert, After Update) 
    Group grp = new Group();
    for(Contact ContactObj : [select Id, xrx_mf_crm__Region_1__c from  Contact where Id IN: Trigger.New]){
        string Region = ContactObj.xrx_mf_crm__Region_1__c;
        List<ContactShare> sharesToCreate = new List<ContactShare>();
        if (Region) {
            ID groupId = [select id from Group where Name = :Region].id;
            ContactShare cs = new ContactShare();
            cs.ContactAccessLevel = 'Edit';
            cs.ContactId = contactObj.Id;
            cs.UserOrGroupId =  groupId.id;
        if (!sharesToCreate.isEmpty())
            insert sharesToCreate;
  • Set contact as private or read the only in sharing setting. ?
    – MIX DML
    May 1, 2015 at 19:20

2 Answers 2


In Setup -> Security Controls -> Sharing Settings, you would need contacts to be set to Private vs Controlled by Parent in order to be able to write to that field.

On a side note, you may want to also look into moving your groupId query outside of your for loop. You should also be able to access the xrx_mf_crm__Region_1__c field without querying for it by looping through the list of records in the trigger something like:

for (Contact contact : Trigger.new)

It looks like there is a blog post that should help you through this trigger too, here.

  • Thanks Jenny for Answering my query. Changing the sharing setting to private helped to resolve the issue.
    – Dinesh
    May 1, 2015 at 20:20

From what I've seen the ContactAccessLevel field cannot be inserted, but it can be changed with an update once the record is already inserted. You would need to remove the contactaccesslevel='edit' from the insert portion and after that section add something like:

List<ContactShare> shares = [select Id, ContactAccessLevel,  
 RowCause from ContactShare where ContactId IN :Sharestocreate];

for (ContactShare share: shares)

update shares;

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