function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
John NeilanJohn Neilan 

Trigger Error

Hi Everyone,

I have a custom object (Account_Manager_Handoff__c) with a Mast-Detail relationship to the Opportunity object.  The trigger below is meant to fire when the custom object is created or edited.  In either case, a field on the associated Account (Account_Manager_Handoff_Notes__c) gets updated with some text values from the custom object.  In addition, if another checkbox field (Handoff_Official__c) is marked as TRUE, the Account Owner is supposed to be changed to the person indicated in the Assigned_Account_Manager__c field on the custom object, and the related Opportunity (Opportunity__c) on the custom object is supposed to be cloned.  The trigger saves without errors, but when I try to create a record I get the following error:

MainTriggerAccountManagerHandoff: execution of AfterInsert caused by: System.FinalException: Record is read-only: Class.ClassAccountManagerHandoffNotes.addNotes: line 21, column 1

Does anyone know why I am getting this error and what I need to do to fix it?

trigger MainTriggerAccountManagerHandoff on Account_Manager_Handoff__c (after insert,after update) {
        if(trigger.isInsert || trigger.isUpdate){
                ClassAccountManagerHandoffNotes updater = new ClassAccountManagerHandoffNotes();

Trigger Class:
public class ClassAccountManagerHandoffNotes {
    public void addNotes(List<Account_Manager_Handoff__c> accountManagerHandoffs){
        Set<Id> accountsInTrigger = new Set<Id>();
        Map<Id,String> accountMap = new Map<Id,String>();
        Map<Id,Id>accountMap2 = new Map<Id,Id>();
        List<Account> accountsToUpdate = new List<Account>();
        FOR(Account_Manager_Handoff__c amh : accountManagerHandoffs){
            IF(amh.AccountLookup__c != NULL){
            String notes = amh.Platform_Experience__c + '\n\n' + amh.Issues_Encountered__c + '\n\n' + amh.Known_Goals__c + '\n\n' + amh.Additional_Notes__c;
            Id owner = amh.Assigned_Account_Manager__c;

//Clone the Opportunity that is associated with the handoff and all createable fields 
            IF(amh.Handoff_Official__c = TRUE){
                /* query Opportunity and then clone it */
                String soql = RecClone.getCreatableFieldsSOQL('Opportunity','Id =: amh.Opportunity__c.Id');
                    Opportunity opp = (Opportunity)Database.query(soql);
                    Opportunity opp2 = opp.clone(false, true);
                insert opp2;

        FOR(Account a : [SELECT Id,Account_Manager_Handoff_Notes__c,OwnerId
                         FROM Account
                         WHERE Id In :accountsInTrigger]){
                            a.Account_Manager_Handoff_Notes__c = accountMap.get(a.Id);

                        FOR(Account_Manager_Handoff__c amh2 : [SELECT Id,Handoff_Official__c
                                                                FROM Account_Manager_Handoff__c
                                                                WHERE Id =: a.Id]){

                            IF(amh2.Handoff_Official__c = TRUE){
                            a.OwnerId = accountMap2.get(a.Id);

        UPDATE accountsToUpdate;        

Class for Clone:
//This class is used to clone all the creatable fields on objects for use with Apex cloning.

public with sharing class RecClone{ 
    // Returns a dynamic SOQL statement for the whole object, includes only creatable fields since we will be inserting a cloned result of this query
    public static string getCreatableFieldsSOQL(String objectName, String whereClause){
        String selects = '';
        if (whereClause == null || whereClause == ''){ return null; }
        // Get a map of field name and field token
        Map<String, Schema.SObjectField> fMap = Schema.getGlobalDescribe().get(objectName.toLowerCase()).getDescribe().Fields.getMap();
        list<string> selectFields = new list<string>();
        if (fMap != null){
            for (Schema.SObjectField ft : fMap.values()){ // loop through all field tokens (ft)
                Schema.DescribeFieldResult fd = ft.getDescribe(); // describe each field (fd)
                if (fd.isCreateable()){ // field is creatable
        if (!selectFields.isEmpty()){
            for (string s:selectFields){
                selects += s + ',';
            if (selects.endsWith(',')){selects = selects.substring(0,selects.lastIndexOf(','));}
        return 'SELECT ' + selects + ' FROM ' + objectName + ' WHERE ' + whereClause;    

Best Answer chosen by John Neilan
Try using Conditional operator '=='
IF(amh.Handoff_Official__c == TRUE)


All Answers

Try using Conditional operator '=='
IF(amh.Handoff_Official__c == TRUE)

This was selected as the best answer
John NeilanJohn Neilan
Wow, that would have been a much simpler error message!  That did the trick for getting rid of the error.  Thanks so much!!