Fixing error: cannot read property “values” from undefined

Typeerror: cannot read property “values” from undefined is one of the most persistent and frequent errors you can get when doing any type of scripting in Google Apps Script. One of the most frequent questions I get on this blog, so I decided to dedicate a post to helping people troubleshoot this pesky error.

First, we’ll talk about what this error means, then we’ll look at the two most common scenarios in which you might get this error, and finally, we’ll talk about what we can do to fix it.

What does typeerror: cannot read property “values” from undefined really mean?

To understand this, you first need to understand what it means to be undefined in JavaScript. Let’s take a look at a simple example using variables:

// This line is a variable declaration
// we create it, but do not assign it a value 
// so it is undefined

var a; 

// In this line we declare and assign a variable
// this is not undefined 

var b = 6;

Something is undefined in JavaScript when it is an object that is expected to hold a reference to a value, but in fact references nothing. There is a really good explanation at W3 schools on undefined in JS that is worth a look if you want some better examples.

In the context of our error message, it says we are trying to read a set of properties called “values” from something that is undefined, likely with a line that looks something like this if you are using the resources on this site:

var email = e.values[4];

When the script runs, it gets to this line or a line like it and and says “Ok, I see you want to create a variable called email, and you want this variable to equal the 5th value of something called e (our form submission event), but wait a minute, e is undefined! There is nothing there! Error!”

The event parameter (e) exists because we injected it into the script, but it doesn’t equal anything, so in turn we can’t access any of its properties. In the case of most Google Apps Scripts projects, this occurs because there is not event (e) passed in when you run the script in the debugger.

What Can I Do to Fix This in Google Apps Script? 

For most people, this is a quick fix: Submit a test form. DO NOT TRY TO RUN IN DEBUGGER. 

Remember the script needs an event, meaning we have to give it one. Since we’ve set a trigger tied to a form submission, that is the type of event that it expects.

 

 

 

I'm working on building the most comprehensive course available on building workflows with Google Apps Script.

Join the Course Waiting List for a Huge Discount!

* indicates required

14 thoughts on “Fixing error: cannot read property “values” from undefined”

  1. Arthur says:

    Hello,
    I have a problem with my forms I have this error but I send a test form but I have the same problem. Can you help me ?

    1. admin says:

      Can you post your code for me to look at?

      1. Curt Painter says:

        I am curious if there was a solution. I am having the same problem as Arthur. I have pasted my code below:

        function lunchDetention(e)
        {
        var studentName = e.values[4];
        var detentionDate = e.values[3];

        startDate = new Date(detentionDate);
        endDate = new Date( detentionDate);

        var startDate = new Date( );

        var myCal = CalendarApp.getDefaultCalendar( );

        myCal.createAllDayEvent(studentName,detentionDate);

        }

        1. BrownBearWhatDoYouSee says:

          First, make sure you are testing this by submitting a test form. Can you confirm you are doing that?

          This issue usually indicates an issue with a typo in the function, or a mis-referenced spreadsheet cell. Are you sure that the values (e.values[4] and e.values[3]) are correct using zero indexing, meaning the first column of the spreadsheet (usually the timestamp) is e.values[0]?

          If it’s not that, there are other things you can try as well.

  2. Lounhass says:

    Hello

    same goes for me.

    I copied and pasted your script but I keep getting the error message even though I added the correct values

    Please help me!

  3. ITGuide says:

    Hi Jeff,

    I’m liking this blog on Google App Scripts!

    I suspect you may have the answer to this already but 1 way around this that I found handy is to use javascript “try” and “catch” block. This worked for me.

    https://stackoverflow.com/questions/17180141/how-do-you-pass-back-a-custom-error-message-from-google-apps-scripts

    All you have to do to ignore the error is to leave your error handling empty.

    try{
    // function code goes here;
    }catch(e){
    // igore error
    // or if you prefer display an error message here
    }

    1. BrownBearWhatDoYouSee says:

      Thanks for the link! You’re right that try/catch is a great paradigm for error handling and has tons of applications for making robust Google Apps. Thanks for reading!

  4. nicol biden says:

    This error occurs in Chrome Browser when you read a property or call a method on an undefined object . Uncaught TypeError: Cannot read property of undefined error is probably easiest to understand from the perspective of undefined, since undefined is not considered an object type at all (but its own undefined type instead), and properties can only belong to objects within JavaScript. There are a few variations of this error depending on the property you are trying to access. Sometimes instead of undefined it will say null.

    http://net-informations.com/js/iq/unerror.htm

    1. BrownBearWhatDoYouSee says:

      Thanks for the link to the helpful resource. JE

  5. OH Please help… I have tried every tip tool and resource I can find to fix the failed to run error.
    I had the undefined error in debugger. The try/catch fixed that just to check the code.
    But I still get a failed trigger and the template isn’t created when I submit test form after test form after test form.
    //here is my code:
    function CreateSOI(e) {
    //e.values is an array of form values
    var timestamp = e.values[0];
    var lastname = e.values[1];
    var firstname = e.values[2];
    var grade = e.values[3];
    var age = e.values[4];
    var dateadmin = e.values[5];
    var cfu = e.values[6];
    var cfc = e.values[7];
    var mfu = e.values[8];
    var efu = e.values[9];
    var efc = e.values[10];
    var cfs = e.values[11];
    var cft = e.values[12];
    var nfu = e.values[13];
    var dfu = e.values[14];
    var css = e.values[15];
    var msuv = e.values[16];
    var mssv = e.values[17];
    var msua = e.values[18];
    var mssa = e.values[19];
    var msi = e.values[20];
    var esc = e.values[21];
    var ess = e.values[22];
    var nss = e.values[23];
    var nst = e.values[24];
    var nsi = e.values[25];
    var dsr = e.values[26];
    var csr = e.values[27];
    var cmu = e.values[28];
    var cmum = e.values[29];
    var cmr = e.values[30];
    var cms = e.values[31];
    var dmu = e.values[32];
    var mmi = e.values[33];
    var figural = e.values[34];
    var symbolic = e.values[35];
    var semantic = e.values[36];
    var creativity = e.values[37];
    var memory = e.values[38];
    var evaluation = e.values[39];
    var formversion = e.values[40];

    //file is the template file, and you get it by ID
    var file = DocumentApp.getFileById(‘1DcJvrFF_8sZQgL3hc1J4GdJ9spTfDNGo6QG642HGgq4′);

    //We can make a copy of the template, name it, and optionally tell it what folder to live in
    //file.makeCopy will return a Google Drive file object
    var folder = DriveApp.getFolderById(’17tih1cwh7gZI3yVV6g8UFPbb5SWxIUUH’)
    var copy = file.makeCopy(lastname + ‘.’ + firstname + ‘SOIclusterFormCR’, folder);

    //Once we’ve got the new file created, we need to open it as a document by using its ID
    var doc = DocumentApp.openById(copy.getId());

    //Since everything we need to change is in the body, we need to get that
    var body = doc.getBody();

    //Then we call all of our replaceText methods
    body.replaceText(‘<>’, timestamp);
    body.replaceText(‘<>’, lastname);
    body.replaceText(‘<>’, firstname);
    body.replaceText(‘<>’, grade);
    body.replaceText(‘<>’, age);
    body.replaceText(‘<>’, dateadmin);
    body.replaceText(‘<>’, cfu);
    body.replaceText(‘<>’, cfc);
    body.replaceText(‘<>’, mfu);
    body.replaceText(‘<>’, efu);
    body.replaceText(‘<>’, efc);
    body.replaceText(‘<>’, cfs);
    body.replaceText(‘<>’, cft);
    body.replaceText(‘<>’, nfu);
    body.replaceText(‘<>’, dfu);
    body.replaceText(‘<>’, css);
    body.replaceText(‘<>’, msuv);
    body.replaceText(‘<>’, mssv);
    body.replaceText(‘<>’, msua);
    body.replaceText(‘<>’, mssa);
    body.replaceText(‘<>’, msi);
    body.replaceText(‘<>’, esc);
    body.replaceText(‘<>’, ess);
    body.replaceText(‘<>’, nss);
    body.replaceText(‘<>’, nst);
    body.replaceText(‘<>’, nsi);
    body.replaceText(‘<>’, dsr);
    body.replaceText(‘<>’, csr);
    body.replaceText(‘<>’, cmu);
    body.replaceText(‘<>’, cmum);
    body.replaceText(‘<>’, cmr);
    body.replaceText(‘<>’, cms);
    body.replaceText(‘<>’, dmu);
    body.replaceText(‘<>’, mmi);
    body.replaceText(‘<>’, figural);
    body.replaceText(‘<>’, symbolic);
    body.replaceText(‘<>’, semantic);
    body.replaceText(‘<>’, creativity);
    body.replaceText(‘<>’, memory);
    body.replaceText(‘<>’, evaluation);

    //Lastly we save and close the document to persist our changes
    doc.saveAndClose();

    }

  6. I GOT IT …. OMG I GOT IT!!! Super Proud of myself!

    The error issue was that I had previously tried to run autocrat add on to achieve same end result and while I had deleted its components it was still causing issues with my new script. The autocrat not being reliable is the whole reason I chose to find and write the script instead.

    THANK YOU for this!

    I am now taking it a step further to generate 4 documents perform submit all with the same data.

    1. BrownBearWhatDoYouSee says:

      Awesome! I’m glad you got everything figured out. Thanks for reading, and be sure to post back if you hit anymore road blocks.

      JE

  7. Hazel says:

    Hi! Thanks for much for posting! I am filtering my form responses into various tabs based on Col2. I’d like for all responses from each tab to populate a doc in a folder for that tab.

    1. Should I be filtering in the responses sheet like I currently am or would it be better to write a filter into the function? If so how?

    2. If filtering first is best, how do I define which tab the values come from?

    1. BrownBearWhatDoYouSee says:

      I’m not sure what you mean by filtering here. Can you post an example of some code?

      Thanks for reading,
      Jeff

Leave a Reply

Your email address will not be published. Required fields are marked *