I am getting this error whenever my Process builder calls an Apex Class. I'm not sure if this is allowed so I'd like to ask for your input.

So basically, my Process Builder is in the Case object and it is triggered when User sends an email to a Queue.

When this happens, the Process Builder then calls an Apex class with an invocable method below:

    public static void methodA(List<Case> caseList) {

    //do some SOQL code here to determine xxxxxxxx

    for(Case c : caseList) {
        c.contactId = 'xxxxxxxx';
    update caseList;        

Basically, the method just changes the contact Id of the case to something else and then updates the Case.

However, I instead get this error every time I send an email to the Queue.

An Apex error occurred: System.FinalException: Record is read-only

It would seem that I am not allowed to update the contactId of the Case. Is this correct? If so, then how can I update the contactId of the Case by the Apex Class?


  • Do you have any trigger written on case? – Tushar Sharma Sep 26 '18 at 6:49
  • Rather than calling invocable method, you could update in PB field update action – Santanu Boral Sep 26 '18 at 6:57
  • there is a trigger in the case but it is for a different action. I don't think it is related to this or has any affect on this. – Jerard Dela Victoria Sep 26 '18 at 7:25

let me guess, that records, that are sent to Apex are sent from Process as "Select the Case record that started your process". According to the Order of Execution process is launched after after triggers. And if you are sending context records, looks like they all have "isReadOnly" flag on the sObject records. This flag is responsible for causing the FinalException. This is similar to situation, when you are trying to change trigger context records in after trigger event. In order to update records from current transaction, create new Case record with predefined Id.

public static void methodA(List<Case> caseList) {
    List<Case> toUpdate = new List<Case>();
    for(Case c : caseList) {
        toUpdate.add(new Case(
            Id = c.Id,
            ContactId = 'xxxxxxxx';
    update toUpdate;
| improve this answer | |
  • Thanks for this example. I tried adding your AsyncUpdater code and see if it works but I still get the issue when I call AsyncUpdater.run. The error is still about read-only. – Jerard Dela Victoria Sep 26 '18 at 7:23
  • @JerardDelaVictoria I have updated my answer, check this variant – Oleksandr Berehovskyi Sep 26 '18 at 7:51
  • my friend, your code works! Thank you so much! I knew that I was missing something, but I just couldn't figure out what it was. Your explanation was also clear and it helped me understand where I got it wrong. Again, this code now works and thank you very much! – Jerard Dela Victoria Sep 26 '18 at 8:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.