I really need help understanding a trigger i'm trying to code.

I want a trigger who willpopulate the field "What" (field label: "Related to") of an event with the Account's related opportunity when an event is created or updated.

The Trigger is working when I create or update an event in the sandbox. But if I remove the try/catch block, it doesn't anymore for before insert (before update works fine), since an exception is raised:

execution of BeforeInsert caused by: System.QueryException: List has no rows for assignment to SObject.

Why does the trigger have intended behavior with the try/catch block? Any way of removing it?

I know i'm new to coding apex, and did query in a loop, etc. sorry in advance. Best practices tips are appreciated, but please focus on my question.

Any help would be hugely appreciated.

My trigger code:


//if name of event is "discovery meeting" or "follow up meeting"
//query account ID on event and store in a variable
//query opportunity related to account
//populate the whatid field of the event with the opportunity ID

trigger Populate_Event on Event (before insert, before update) {

for (Event Meeting : Trigger.new) {

    if ((Meeting.subject == 'Discovery Meeting')||(Meeting.subject == 'Follow-up Meeting')){
        ID account_id = meeting.accountid;
        //need to catch the exception since before insert will fail
        try {
            opportunity opp = [select id FROM Opportunity Where AccountId = :account_id];
            meeting.whatid = opp.id;
        catch (System.QueryException e) {

            System.debug('Catch Query exception');
  • When is meeting.accountid populated? It sounds like either triggers are not executing in the order you expect or objects are inserted asynchronously by the app. Oct 24, 2016 at 2:58
  • The field event.accountId is not updateable unfortunately :/
    – Werlin
    Oct 24, 2016 at 3:58

1 Answer 1


1) avoid SQL in for loop, very bad practice, it's called bulkify your code the use of Map will help you ;-)

2) Even if it will return 1 opportunity only, always use a list, Salesforce always returns you a list of opportunity, then try to assign the first element of the list to your opp. That's why you are getting List has no rows for assignment to SObject. so transform :

opportunity opp = [select id FROM Opportunity Where AccountId = :account_id];


opportunity[] opp = [select id FROM Opportunity Where AccountId = :account_id];

3) AccountId is populated automatically from the UI when you create an event from a contact now from test class I think you will need to populate that yourself (to confirm), probably make sure in your trigger that accountid is not blank before to execute the rest.

  • Thanks for your answer and tips. I will read the info and work on that.
    – Werlin
    Oct 24, 2016 at 3:59
  • I used a list like you suggested, but I now get "list index out of bounds" exception. I know for certain there IS an opportunity record..
    – Werlin
    Oct 25, 2016 at 22:25
  • @JeanCadieux if you are running in test context you have to create your own test data. Prod data is not visible by default during tests
    – Eric
    Oct 26, 2016 at 7:00
  • @Eric Thanks, I already did. Unfortunately that's not my question :/
    – Werlin
    Oct 26, 2016 at 7:13
  • @JeanCadieux did you debug the results of your query? Is it returning any records
    – Eric
    Oct 26, 2016 at 7:14

You must log in to answer this question.

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