Top 10 JavaScript errors from 1000+ projects (and how to avoid them)
Tags: javascript, webdev, react
Published: 2018-01-29 19:15:35

---
title: Top 10 JavaScript errors from 1000+ projects (and how to avoid them)
published: true
description: We looked at our database of thousands of projects and found the top 10 errors in JavaScript. We’re going to show you what causes them and how to prevent them from happening. If you avoid these "gotchas," you can be a better developer.
tags: #javascript, #webdev, #react
cover_image: https://thepracticaldev.s3.amazonaws.com/i/8rkbw39rrdie8561kcyy.png
canonical_url: https://rollbar.com/blog/top-10-javascript-errors/
---

_Note: This was originally published on [Rollbar's blog](https://rollbar.com/blog/top-10-javascript-errors/)._

To give back to our community of developers, we looked at our database of thousands of projects and found the top 10 errors in JavaScript. We’re going to show you what causes them and how to prevent them from happening. If you avoid these "gotchas," it'll make you a better developer.

Because data is king, we collected, analyzed, and ranked the top 10 **[JavaScript errors](https://rollbar.com/error-tracking/javascript/)**. Rollbar collects all the errors for each project and summarizes how many times each one occurred. We do this by grouping errors according to their **[fingerprints](https://rollbar.com/docs/grouping-algorithm/)**. Basically, we group two errors if the second one is just a repeat of the first. This gives users a nice overview instead of an overwhelming big dump like you’d see in a log file.

We focused on the errors most likely to affect you and your users. To do this, we ranked errors by the number of projects experiencing them across different companies. If we looked only at the total number of times each error occurred, then high-volume customers could overwhelm the data set with errors that are not relevant to most readers.

**Here are the top 10 JavaScript errors**:

![Screenshot of javascript error graph](https://rollbar.com/assets/blog/images/top-10-javascript-errors/javascript-error-graph.png)
<!--more-->

Each error has been shortened for easier readability. Let’s dive deeper into each one to determine what can cause it and how you can avoid creating it.

## 1. Uncaught TypeError: Cannot read property

If you’re a JavaScript developer, you’ve probably seen this error more than you care to admit. This one occurs in Chrome when you read a property or call a method on an undefined object. You can test this very easily in the Chrome Developer Console.

![Screenshot of Uncaught TypeError: Cannot read property](https://rollbar.com/assets/blog/images/top-10-javascript-errors/cannot-read-property.png)

This can occur for many reasons, but a common one is improper initialization of state while rendering the UI components. Let’s look at an example of how this can occur in a real-world app. We’ll pick React, but the same principles of improper initialization also apply to Angular, Vue or any other framework.

```js
class Quiz extends Component {
  componentWillMount() {
    axios.get('/thedata').then(res => {
      this.setState({items: res.data});
    });
  }

  render() {
    return (
      <ul>
        {this.state.items.map(item =>
          <li key={item.id}>{item.name}</li>
        )}
      </ul>
    );
  }
}
```

There are two important things realize here:

1. A component’s state (e.g. `this.state`) begins life as `undefined`.
2. When you fetch data asynchronously, the component will render at least once before the data is loaded – regardless of whether it’s fetched in the constructor, `componentWillMount` or `componentDidMount`. When Quiz first renders, `this.state.items` is undefined. This, in turn, means `ItemList` gets items as undefined, and *you* get an error – "Uncaught TypeError: Cannot read property ‘map’ of undefined" in the console.

This is easy to fix. The simplest way: Initialize state with reasonable default values in the constructor.

```js
class Quiz extends Component {
  // Added this:
  constructor(props) {
    super(props);

    // Assign state itself, and a default value for items
    this.state = {
      items: []
    };
  }

  componentWillMount() {
    axios.get('/thedata').then(res => {
      this.setState({items: res.data});
    });
  }

  render() {
    return (
      <ul>
        {this.state.items.map(item =>
          <li key={item.id}>{item.name}</li>
        )}
      </ul>
    );
  }
}
```

The exact code in your app might be different, but we hope we’ve given you enough of a clue to either fix or avoid this problem in your app. If not, keep reading because we’ll cover more examples for related errors below.

## 2. TypeError: ‘undefined’ is not an object (evaluating

This is an error that occurs in Safari when you read a property or call a method on an undefined object. You can test this very easily in the Safari Developer Console. This is essentially the same as the above error for Chrome, but Safari uses a different error message.

![Screenshot of TypeError: ‘undefined’ is not an object (evaluating](https://rollbar.com/assets/blog/images/top-10-javascript-errors/undefined-is-not-an-object.png)

## 3. TypeError: null is not an object (evaluating

This is an error that occurs in Safari when you read a property or call a method on a null object. You can test this very easily in the Safari Developer Console.

![Screenshot of TypeError: null is not an object (evaluating](https://rollbar.com/assets/blog/images/top-10-javascript-errors/null-is-not-an-object.png)

Interestingly, in JavaScript, null and undefined are not the same, which is why we see two different error messages. Undefined is usually a variable that has not been assigned, while null means the value is blank. To verify they are not equal, try using the strict equality operator:

![Screenshot of TypeError: null is not an object (evaluating](https://rollbar.com/assets/blog/images/top-10-javascript-errors/null-is-not-an-object1.png)

One way this error might occur in a real world example is if you try using a DOM element in your JavaScript before the element is loaded. That’s because the DOM API returns null for object references that are blank.

Any JS code that executes and deals with DOM elements should execute after the DOM elements have been created. JS code is interpreted from top to down as laid out in the HTML. So, if there is a tag before the DOM elements, the JS code within script tag will execute as the browser parses the HTML page. You will get this error if the DOM elements have not been created before loading the script.

In this example, we can resolve the issue by adding an event listener that will notify us when the page is ready. Once the `addEventListener` is fired, the `init()` method can make use of the DOM elements.

```js
<script>
  function init() {
    var myButton = document.getElementById("myButton");
    var myTextfield = document.getElementById("myTextfield");
    myButton.onclick = function() {
      var userName = myTextfield.value;
    }
  }
  document.addEventListener('readystatechange', function() {
    if (document.readyState === "complete") {
      init();
    }
  });
</script>

<form>
  <input type="text" id="myTextfield" placeholder="Type your name" />
  <input type="button" id="myButton" value="Go" />
</form>
```

## 4. (unknown): Script error

The Script error occurs when an uncaught JavaScript error crosses domain boundaries in violation of the cross-origin policy. For example, if you host your JavaScript code on a CDN, any uncaught errors (errors that bubble up to the window.onerror handler, instead of being caught in try-catch) will get reported as simply "Script error" instead of containing useful information. This is a browser security measure intended to prevent passing data across domains that otherwise wouldn’t be allowed to communicate.

To get the real error messages, do the following:

**1. Send the Access-Control-Allow-Origin header**

Setting the `Access-Control-Allow-Origin` header to * signifies that the resource can be accessed properly from any domain. You can replace * with your domain if necessary: for example, `Access-Control-Allow-Origin: www.example.com`. However, handling multiple domains gets tricky, and may not be worth the effort if you’re using a CDN due to caching issues that may arise. See more **[here](http://stackoverflow.com/questions/1653308/access-control-allow-origin-multiple-origin-domains)**.

Here are some examples on how to set this header in various environments:

**_Apache_**

In the folders where your JavaScript files will be served from, create an `.htaccess` file with the following contents:

```
Header add Access-Control-Allow-Origin "*"
```

**_Nginx_**

Add the add_header directive to the location block that serves your JavaScript files:

```
location ~ ^/assets/ {
    add_header Access-Control-Allow-Origin *;
}
```

**_HAProxy_**

Add the following to your asset backend where JavaScript files are served from:

```
rspadd Access-Control-Allow-Origin:\ *
```

**2. Set crossorigin="anonymous" on the script tag**

In your HTML source, for each of the scripts that you’ve set the `Access-Control-Allow-Origin` header for, set `crossorigin="anonymous"` on the SCRIPT tag. Make sure you verify that the header is being sent for the script file before adding the `crossorigin` property on the script tag. In Firefox, if the `crossorigin` attribute is present but the `Access-Control-Allow-Origin` header is not, the script won’t be executed.

## 5. TypeError: Object doesn’t support property

This is an error that occurs in IE when you call an undefined method. You can test this in the IE Developer Console.

![Screenshot of TypeError: Object doesn’t support property](https://rollbar.com/assets/blog/images/top-10-javascript-errors/Object-doesnot-support-property.png)

This is equivalent to the error "TypeError: ‘undefined’ is not a function" in Chrome. Yes, different browsers can have different error messages for the same logical error.

This is a common problem for IE in web applications that employ JavaScript namespacing. When this is the case, the problem 99.9% of the time is IE’s inability to bind methods within the current namespace to the `this` keyword. For example, if you have the JS namespace `Rollbar` with the method `isAwesome.` Normally, if you are within the `Rollbar` namespace you can invoke the `isAwesome` method with the following syntax:

```js
this.isAwesome();
```

Chrome, Firefox and Opera will happily accept this syntax. IE, on the other hand, will not. Thus, the safest bet when using JS namespacing is to always prefix with the actual namespace.

```js
Rollbar.isAwesome();
```

## 6. TypeError: ‘undefined’ is not a function

This is an error that occurs in Chrome when you call an undefined function. You can test this in the Chrome Developer Console and Mozilla Firefox Developer Console.

![Screenshot of undefined is not a function](https://rollbar.com/assets/blog/images/top-10-javascript-errors/undefined-is-nota-function.png)

As JavaScript coding techniques and design patterns have become increasingly sophisticated over the years, there’s been a corresponding increase in the proliferation of self-referencing scopes within callbacks and closures, which are a fairly common source of this/that confusion.

Consider this example code snippet:

```js
function testFunction() {
  this.clearLocalStorage();
  this.timer = setTimeout(function() {
    this.clearBoard();    // what is "this"?
  }, 0);
};
```

Executing the above code results in the following error: "Uncaught TypeError: undefined is not a function." The reason you get the above error is that when you invoke `setTimeout()`, you are actually invoking `window.setTimeout()`. As a result, an anonymous function being passed to `setTimeout()` is being defined in the context of the window object, which has no `clearBoard()` method.

A traditional, old-browser-compliant solution is to simply save your reference to `this` in a variable that can then be inherited by the closure. For example:

```js
function testFunction () {
  this.clearLocalStorage();
  var self = this;   // save reference to 'this', while it's still this!
  this.timer = setTimeout(function(){
    self.clearBoard();  
  }, 0);
};
```

Alternatively, in the newer browsers, you can use the `bind()` method to pass the proper reference:

```js
function testFunction () {
  this.clearLocalStorage();
  this.timer = setTimeout(this.reset.bind(this), 0);  // bind to 'this'
};

function testFunction(){
    this.clearBoard();    //back in the context of the right 'this'!
};
```

## 7. Uncaught RangeError: Maximum call stack

This is an error that occurs in Chrome under a couple of circumstances. One is when you call a recursive function that does not terminate. You can test this in the Chrome Developer Console.

![Screenshot of Uncaught RangeError: Maximum call stack](https://rollbar.com/assets/blog/images/top-10-javascript-errors/maximum-call-stack.png)

It may also happen if you pass a value to a function that is out of range. Many functions accept only a specific range of numbers for their input values. For example, `Number.toExponential(digits)` and N`umber.toFixed(digits)` accept digits from 0 to 20, and `Number.toPrecision(digits)` accepts digits from 1 to 21.

```js
var a = new Array(4294967295);  //OK
var b = new Array(-1); //range error

var num = 2.555555;
document.writeln(num.toExponential(4));  //OK
document.writeln(num.toExponential(-2)); //range error!

num = 2.9999;
document.writeln(num.toFixed(2));   //OK
document.writeln(num.toFixed(25));  //range error!

num = 2.3456;
document.writeln(num.toPrecision(1));   //OK
document.writeln(num.toPrecision(22));  //range error!
```

# 8. TypeError: Cannot read property ‘length’

This is an error that occurs in Chrome because of reading length property for an undefined variable. You can test this in the Chrome Developer Console.

![Screenshot of TypeError: Cannot read property ‘length’](https://rollbar.com/assets/blog/images/top-10-javascript-errors/cannot-read-property-length.png)

You normally find length defined on an array, but you might run into this error if the array is not initialized or if the variable name is hidden in another context. Let’s understand this error with the following example.

```js
var testArray= ["Test"];

function testFunction(testArray) {
    for (var i = 0; i < testArray.length; i++) {
      console.log(testArray[i]);
    }
}

testFunction();
```

When you declare a function with parameters, these parameters become local ones. This means that even if you have variables with names `testArray`, parameters with the same names within a function will still be treated as **local.**

You have two ways to resolve your issue:

1. Remove parameters in the function declaration statement (it turns out you want to access those variables that are declared outside of the function, so you don’t need parameters for your function):

   ```js
   var testArray = ["Test"];

   /* Precondition: defined testArray outside of a function */
   function testFunction(/* No params */) {
       for (var i = 0; i < testArray.length; i++) {
         console.log(testArray[i]);
       }
   }

   testFunction();
   ```

2. Invoke the function passing it the array that we declared:

   ```js
   var testArray = ["Test"];

   function testFunction(testArray) {
      for (var i = 0; i < testArray.length; i++) {
         console.log(testArray[i]);
       }
   }

   testFunction(testArray);
   ```

## 9. Uncaught TypeError: Cannot set property

When we try to access an undefined variable it always returns `undefined` and we cannot get or set any property of `undefined`. In that case, an application will throw “Uncaught TypeError cannot set property of undefined.”

For example, in the Chrome browser:

![Screenshot of Uncaught TypeError: Cannot set property](https://rollbar.com/assets/blog/images/top-10-javascript-errors/cannot-set-property.png)

If the `test` object does not exist, error will throw “Uncaught TypeError cannot set property of undefined.”

## 10. ReferenceError: event is not defined

This error is thrown when you try to access a variable that is undefined or is outside the current scope. You can test it very easily in Chrome browser.

![Screenshot of ReferenceError: event is not defined](https://rollbar.com/assets/blog/images/top-10-javascript-errors/event-is-not-defined.png)

If you’re getting this error when using the event handling system, make sure you use the event object passed in as a parameter. Older browsers like IE offer a global variable event, but it's not supported on all browsers. Libraries like jQuery attempt to normalize this behavior. Nevertheless, it’s best practice to use the one passed into your event handler function.

```js
function myFunction(event) {
    event = event.which || event.keyCode;
    if(event.keyCode===13){
       alert(event.keyCode);
    }
}
```

## Conclusion
We hope you learned something new and can avoid errors in the future, or that this guide helped you solve a head scratcher. Nevertheless, even with the best practices, unexpected errors do pop up in production. It's important to have visibility into errors that affect your users, and to have good tools to solve them quickly.

Rollbar offers unique features for JavaScript apps like **[telemetry](https://rollbar.com/blog/introducing-javascript-telemetry/)** which tells you what happened on the user’s browser leading up to the error. That’s insight you don’t have outside of your local developer console. Learn more in Rollbar’s full list of **[features for JavaScript applications](https://rollbar.com/error-tracking/javascript/)**.