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

DML statment cannot operate on or trigger.old

I'm trying to write a simple trigger that renames a record. I keep getting the error "CallLineItemRename: execution of BeforeInsert caused by: System.SObjectException: DML statment cannot operate on or trigger.old: Trigger.CallLineItemRename: line 18, column 9" . What am I missing here?




trigger CallLineItemRename on Call_Line_Item__c (before insert, before update) { // this triger renames the call line item id to be // the specified inventory item name or the product name List<Call_Line_Item__c> callItems = new List<Call_Line_Item__c>(); callItems =; for (Call_Line_Item__c callItem : callItems) { //check if inventory or product was specified if (callItem.Inventory_Item__c <> NULL) { callItem.Name = callItem.Inventory_Item__r.Name; callItem.Name = 'inv item name'; } else if (callItem.Products__c <> NULL) { callItem.Name = callItem.Products__r.Name; } } update callItems; }




Best Answer chosen by Admin (Salesforce Developers) 
Remove the update DML statement at the end. By using the "before" trigger to modify the objects, you don't need to explicitly perform an update DML statement. When the trigger ends, it will implicitly update the data as you have modified the values.

All Answers

Remove the update DML statement at the end. By using the "before" trigger to modify the objects, you don't need to explicitly perform an update DML statement. When the trigger ends, it will implicitly update the data as you have modified the values.
This was selected as the best answer
That worked. Though now I'm having an issue because callItem.Inventory_Item__c <> NULL is evaluating to true even when no value is specified in the lookup field. Length() doesn't seem to work. What's the best way to see if a relationship field has been entered? 

What about: callItem.Inventory_Item__c != null

Not sure if that evalutes any different...but worth a shot. 


I'm getting the same error from an after insert/after update trigger.  The goal is to update the triggering object so that the trigger can ignore that object on subsequent updates. 


Sample code (edited for brevity):



trigger NotifyTPAOfBug on Case (after insert, after update) { for(Case c : { if ( c.Status == 'Closed' && c.BugNoteSent__c == FALSE ) { Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); Messaging.sendEmail(new Messaging.Email[] { email }); c.BugNoteSent__c = TRUE; update c; } } }




Force QueryForce Query


           When  remove  the update statement ,it works but it creates one  new record ,previous record is not updated,actually there is no updation,it is inserted as a new record,how can i update the field of existing record at the time of insert?

please help me................



Thanking  You....


Worked for me! Thank you!

Team WorksTeam Works


Its bit confusing : Sometimes it works without update/insert state,ments and sometime it doesnt(before triggers)...ANy explanation please..

Example 1 do not work without insert statement

trigger updatevendor on Opportunity (before insert,before update)
List<Vendor__c> vends= new List<Vendor__c>();
Map<ID,Opportunity> campIdOppMap = new Map<ID,Opportunity> ();
//lets itereate thru the opportunity in the i.e. the opportunities being inserted
for (Opportunity t :{
if (t.CampaignId!= null & t.LeadSource=='Web' )
system.debug('The selected opportunity for the update is '+t);
//this map will hold the campaignID of the campaigns associated with the opportunities(being inserted) and the opportunity record

//The custom object also holds the campaignId to which it is related in campaign__c
//So lets SELECT the records from custom object vendor__c which is associated to the campaignIds collected in map
//i.e. campaign__c = campIdOppMap.keyset() and then iterate thru them
for (Vendor__c cv : [Select Campaign__c,,updatevendor__c From Vendor__c where Campaign__c IN :campIdOppMap.keyset()]){
//as it is a before trigger we do not need to write the update/insert statement
system.debug(cv.Campaign__c +'The values in campaign__c and cv.campaign__r.Id '+ cv.campaign__r.Id );

cv.updatevendor__c= campIdOppMap.get(cv.Campaign__c).Amount;
system.debug('The amount field has this value in the opportunity'+cv.updatevendor__c);
system.debug('Here is the list to be inserted'+vends);
upsert vends;


Example 2 : works without the insert/update statement

trigger ChangeNegativeQuantity on OpportunityLineItem (before insert) {


List<OpportunityLineItem> products =;

for(OpportunityLineItem p : products){

Opportunity opty = [SELECT RecordtypeId,Type FROM Opportunity WHERE id = :p.opportunityId];

if (opty.RecordTypeId == '01290000000ggQ2AAI' ) {
p.Quantity *= -1.0;


ThankQ so much
You don't need the line update callItems; You're using a before trigger and making changes to the objects in Tigger.New. An update is implicit.
smovies guidessmovies guides
Pay your bill online using the MetroPCS Payment Card. This card is compatible with mobile phones using MetroPCS prepaid connection. You have an option to