i wrote a function inside event trigger handler that should receive custom times for a meeting, a custom time zone of the customer, and a timezone for the user - and calculate the time of the meeting according to the user's timezone.

for example:

Customer_Time_Zone__c : GMT -5

User's Time Zone: GMT + 2

Start_Customer_Time_Zone__c : 10:00am

End_Customer_Time_Zone__c: 11:00am

The function will receive this data and calculate that the standard time of the meeting is 17:00pm-18:00 in the user's timezone, and fill the event standard time fields StartDateTime, EndDateTime.

The problem is: i can't do that, because the fields are read only. i have no idea how to update these fields, and if there are more fields that are related to them such as duration etc.

Here is the function so far:

private static void updateStandartDateTimeFields(User u, Event e)
        System.debug('updateStandartDateTimeFields start');
        System.debug('User: ' + u);
        System.debug('Event: ' + e);

        e.StartDateTime = e.Start_Customer_Time_Zone__c;
        e.EndDateTime = e.End_Customer_Time_Zone__c;

        Update e;

When I run a test I receive the following error:

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, EventTrigger: execution of AfterInsert
caused by: System.FinalException: Record is read-only

Class.EventTriggerHandler.updateStandartDateTimeFields: line 131, column 1
Class.EventTriggerHandler.createMeeting: line 59, column 1
Class.EventTriggerHandler.afterInsert: line 31, column 1
Class.TriggerHandler.run: line 45, column 1
Trigger.EventTrigger: line 13, column 1: []

Can I avoid this error? If so, how?

  • 1
    Looks like you have your trigger on after insert and after update events. Why don't you perform the update on before events?
    – Raul
    Jun 26, 2017 at 11:22
  • I have to do it on after update for other reasons. is there a way i can do this in after update?
    – Dana Griff
    Jun 26, 2017 at 11:36
  • You should really clarify those "other reasons" because there's probably a different way to handle them.
    – Adrian Larson
    Jun 26, 2017 at 11:38
  • not reasons i'm aware of, its a code of other developers, i just know that it has to occure in "after update"
    – Dana Griff
    Jun 26, 2017 at 11:46
  • @D.Griff Well you should push back on them to provide better justification. Doing a field update in an after context clearly violates Salesforce's own recommendations on trigger best practice.
    – Adrian Larson
    Jun 26, 2017 at 13:23

1 Answer 1


Field updates belong in a before trigger and do not require additional DML operations. I suggest you have a read of Triggers from the Apex Developer Guide:

You can define triggers for top-level standard objects that support triggers, such as a Contact or an Account, some standard child objects, such as a CaseComment, and custom objects. To define a trigger, from the object management settings for the object whose triggers you want to access, go to Triggers.

There are two types of triggers:

  • Before triggers are used to update or validate record values before they’re saved to the database.
  • After triggers are used to access field values that are set by the system (such as a record's Id or LastModifiedDate field), and to affect changes in other records, such as logging into an audit table or firing asynchronous events with a queue. The records that fire the after trigger are read-only.

If you really must use an after context, you can't operate on the context records, but rather must create new ones.

List<Event> toUpdate = new List<Event>();
for (Event record : trigger.new)
    toUpdate.add(new Event(Id=record.Id, /*other data*/));
update toUpdate;
  • Having a check for Recursive Trigger Calls is nice to have/necessary.
    – Raul
    Jun 26, 2017 at 12:59
  • 1
    Well... not if you use before events but yeah you are right. Although I find appropriate filters to do the job 99% of the time.
    – Adrian Larson
    Jun 26, 2017 at 13:08

You must log in to answer this question.

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