Exeception on After Insert, Record is read only

I’m writing a trigger for new opportunity products to populate a field Product_Category__c (on opportunity lineitem) getting the value from Product_Category_new__c (on Product).

This is my trigger:

trigger SetProductCategory on OpportunityLineItem (after insert) {

    for (OpportunityLineItem opplineitem: Trigger.new) {           
        opplineitem.Product_Category__c =  opplineitem.PricebookEntry.Product2.Product_Category_new__c;

I get this error message:

execution of AfterInsert caused by: System.FinalException: Record is read-only

I have tried with before insert;in this case there aren’t errors but the value Product category it’s not saved on Opportunity Line item.

I have found that:

In a after insert trigger is not allowed change field using trigger.new

Please can you suggest a solution for this? i would like to copy the value Product category (Product) on Product Category (Opportunity Product) after the insert of the new opportunity products.

Thanks in advantage for any advice.



The record is locked because you are catching the record after the insert DML statement has happened. So if you’d like to modify this record (or records), you will need to query anew, modify, then execute another DML statement.

Here is an example of how you could modify your trigger to work:

trigger SetProductCategory on OpportunityLineItem (after insert) {

    List<OpportunityLineItem> olis = [SELECT Id, PricebookEntry.Product2.Product_Category_new__c FROM OpportunityLineItem WHERE Id IN: Trigger.newMap.keySet()];

    for (OpportunityLineItem opplineitem: olis){
        opplineitem.Product_Category__c= opplineitem.PricebookEntry.Product2.Product_Category_new__c;

    update olis;


And of course, since it’s a trigger, we want to be sure to work in batches — that’s why I’m updating a list of olis rather than an individual opp line item.

Source : Link , Question Author : Enry , Answer Author : Tim Smith

Leave a Comment