Debugging: "Cannot read property 'length' of undefined."
Tags: javascript, webdev, errors, debugging
Published: 2019-10-01 13:20:56

---
title: Debugging: "Cannot read property 'length' of undefined."
published: true
tags: javascript,webdev,error,debugging
canonical_url: https://trackjs.com/blog/debugging-cannot-read-property-length-of-undefined/
cover_image: https://trackjs.com/assets/images/blog/2019-09-debugging-cannot-read-property-length-of-undefined.png
---

While looking into an [issue with Microsoft Edge and the Facebook sdk](https://trackjs.com/blog/debugging-edge-failed-to-construct-request-invalid-argument/) a few weeks ago, we ran into a very common error: `Cannot read property ‘length’ of undefined`. In fact, this is the 6th most common error, affecting nearly 28% of accounts.

This error indicates that our code expects to have an object with a `length` property, but that object was not present. `length` is commonly used on `string` and `array`, but a custom object could also have this property.

This is a **blocking error** , and execution will stop. It is important to defensively typecheck data passed in from external scripts and systems before interacting with them.

## Root Cause

This error can be thrown for a lot of reasons, as it is incredibly common to reference the `length` property of `string` or `array` during everyday development.

In our case, we were [wrapping a JavaScript function](https://trackjs.com/blog/how-to-wrap-javascript-functions/) to intercept `fetch` requests for instrumentation, and we had expected the `url` property as defined in the [fetch specification](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch) would be a string.

The Facebook sdk didn’t call `fetch` with a string. They called it with a serializable object. 🤦‍♂️.

They had built an object similar to the [nodejs Url class](https://nodejs.org/api/url.html), which provides some easier access and utilities to build up a url string. The custom object could be serialized as a url with the implementation of a custom `toString` function. Here is a simplistic example:

```javascript
fetch({ 
  protocol: "https",  
  hostname: "example.com", 
  path: "/foo", 
  toString: function() { 
    return `${this.protocol}://${this.hostname}${this.path}`; 
  } 
});
```

Passing a serializable object into fetch is not in the specification, however it seems to work in all the modern browsers.

Due to the nature of our wrapping of `fetch`, we assumed url to be a different type, and threw an error trying to get the length of something that wasn’t a string.

In my opinion, it would have been better to serialize their url object to a string literal _before_ calling `fetch`, and not rely on _undocumented behavior_ from the browsers. But you can’t rely on external teams to always make sound technical decisions.

## How to Fix

Always defensively check data from external sources, which include api requests, network responses, and function calls from other scripts. If you accept a `string` value, this can take a few different forms:

- A String Literal `"like this"`
- A String Object `new String("like this")`
- A Serializable Object `{ toString: () => "like this" }`

Of course, it can also be `null`, `undefined`, or a totally different unsupported type as well. In most cases, we can simply coerce the value to a string, which will guarantee our string functions work.

Coercing the value to a string is not complicated, and you don’t have to check for all the variations it could be. Let the runtime do that:

```javascript
function myFunc(unknownStringVar stringy) { 
  var knownStringVar = "" + stringy; 
  // go about your day 
}
```

This will serialize string literals, objects, numbers, booleans, and serializable objects into a plain-old string literal that we can safely get the `length`.

JavaScript can fail in lots of interesting ways. Maybe you can’t get the length of undefined, or maybe that network request is sporadically failing in production. [Front-end error monitoring](https://trackjs.com/) from TrackJS gives your team insight into production problems, without needing to learn complex logging tools.