I am trying to write a before update trigger that deletes all of the child records related to a parent when a checkbox is checked. I have another trigger that fires after update to rebuild these items so it has to happen before.

I am not getting an error when I save the code but I am getting an error when I check the box on a record. It says:

Error: Apex trigger DeleteRecipeSheetItems caused an unexpected exception, contact your administrator: DeleteRecipeSheetItems: execution of BeforeUpdate caused by: System.FinalException: Collection is read-only: External entry point"

My code:

trigger DeleteRecipeSheetItems on Recipe_Sheet__c (before update) {

    Set<Id> recShts = Trigger.newmap.keySet();
    List<Recipe_Sheet_Item__c> RecipeItemList = new List<Recipe_Sheet_Item__c>();

    for(Recipe_Sheet__c rec :trigger.new){
        if(rec.Recalculate_Recipe_Sheet_Items__c == True){
            recShts.add(rec.Id); //Stores the Id of the Recipe_Sheet__c in the list

    RecipeItemList = [SELECT Id,Recipe_Sheet__c,Item__c from Recipe_Sheet_Item__c 
        where Recipe_Sheet__c IN: recShts];        

    if(RecipeItemList.size() > 0)
        delete RecipeItemList;

Building on Eric's answer, the code can be cut down to this:

trigger DeleteRecipeSheetItems on Recipe_Sheet__c (before update) {
    Set<Id> ids = new Set<Id>();
    for(Recipe_Sheet__c r : Trigger.new) {
        if (r.Recalculate_Recipe_Sheet_Items__c) {
    delete [SELECT Id from Recipe_Sheet_Item__c where Recipe_Sheet__c IN :ids];        

Are you getting the error on this line:


If so, it is probably because you are setting it equal to the newMap.keyset.

Not sure why you are initializing it with the newMap.keyset().

Just change the line to Set<ID recShts = New Set<ID>()

since you are populating it later


You cannot delete same record in its before update Trigger. Your trigger is defined on "Recipe_Sheet__c ", You are collecting its ID and trying to delete same record. You can delete other records of same Object, but not record itself.

  • The delete is of the child object Recipe_Sheet_Item__c but the trigger is on the parent object Recipe_Sheet__c. – Keith C Jul 30 '14 at 23:12
  • Right.. I missed it.. My bad. Your solution is perfect then – Jitendra Zaa Jul 30 '14 at 23:18

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.