I'm going through the Bulk Apex Trigger module and I can't get to pass the hands on challenge even though my code works correctly.

This is the code I wrote:

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List<Task> tasksToCreate = new List<Task>();

    for (Opportunity a : Trigger.new) {

        if (a.StageName == 'Closed Won') {

            Task newTask = new Task();
            newTask.Subject = 'Follow Up Test Task';
            newTask.WhatId = a.Id;



    if (tasksToCreate.size() > 0) {
        insert tasksToCreate;

Code works fine. I've tested it and it creates a task whenever an opportunity is either created or updated with a status of Closed Won. So why can't I pass the challenges? I get the following error:

enter image description here

I just want to understand whether I'm missing something or the issue is in trailhead doing some weird stuff when checking challenges.

  • Are you sure your trigger is in the trailhead playground org connected to your trailhead account?
    – Derek F
    May 3, 2021 at 14:39
  • Please check your logs on errors because the opportunity can't be created in case if there are some custom fields which are mandatory for filling. Feb 7, 2022 at 16:56

2 Answers 2


I just tested your code in my Trailhead, and it works, which I expected it to, as it meets the design specs. If you're having trouble, make sure that (a) you're using the correct trailhead org, (b) you successfully saved the file (e.g. it didn't have a stray character that caused a compilation error), and (c) you don't have any other triggers or processes that may interfere (e.g. validation rules). If you're still having problems, create a new Trailhead Org and copy the code fresh into that org.

  • 1
    Also close the page, go to the challenge and try to evaluate again after making sure the correct org is selected, and changing it to the correct one if not. Sometimes even though it displays the name of the correct org, it's not actually the one that's set. May 3, 2021 at 15:31

Since you are expecting to work on 'after insert' and ' after update', you need to write DML statement as upsert.

Below is my code and it worked:

trigger ClosedOpportunityTrigger on Opportunity (after insert,after update) {
list<Task> newTask= new list<Task>();
    for(Opportunity oppWon :[Select Id from Opportunity where StageName='Closed Won'
                            and Id in: Trigger.new]){
        newTask.add(new Task (Subject ='Follow Up Test Task',WhatId=oppWon.Id));
        upsert newTask;
  • The part about needing an upsert here is incorrect. The trigger is on Opportunity, not Task, and an Id is not being set on any Task, so an insert is appropriate. An upsert is something you would use if the list you wanted to perform DML on had a mix of records with Ids (existing records, to be updated) and records without Ids (new records, to be inserted).
    – Derek F
    Sep 30, 2021 at 2:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .