Common JavaScript Errors

2021. 6. 29.

Common JavaScript Errors
image by Emile Perron

While developing, you frequently encounter red error messages due to mistakes in the code. It's fortunate if bugs are found during development, but seeing an error message in a live service can make a developer cringe and break out in a cold sweat. Since JavaScript only reveals errors at runtime, serious bugs like these can sometimes be missed. Nowadays, TypeScript and various other tools help mitigate this issue.

An experienced developer might immediately grasp the problem upon seeing an error message, but for average developers like myself, error messages can be bewildering and feel new each time. This post is prepared for those individuals. It should be particularly helpful for developers with relatively less experience.

JavaScript errors are broadly categorized into several types, such as TypeError, SyntaxError, EvalError, InternalError, etc. Error messages can differ slightly between browsers, and even the categorized types might vary. However, they are generally similar. This article will cover only the three most commonly encountered types.

TypeError

TypeError is probably the error you'll encounter most frequently during development. It occurs when you misuse the instance referenced by a variable or argument. This error happens when a variable doesn't contain the value expected by the code, meaning it's not of the expected type. Most often, it's an error indicating that the code attempted to access a member that doesn't exist on the instance referenced by the variable.

Many of these issues would trigger warnings in an IDE or at compile time in statically typed languages. Using TypeScript with JavaScript can cover most of these cases.

TypeError: X is not a function

You've likely seen this error message often. It occurs when you try to execute something that isn't a function. The variable X will contain a value other than a function; it's frequently undefined.

TypeError: X.forEach is not a function
TypeError: X.map is not a function

These are particularly common variations. You received X from somewhere, assumed it was an array, and tried to use array instance methods, but the actual value stored in the X variable was not an array. This error message appears when the object referenced by the X variable lacks the expected method. Since the object doesn't have such a method, it's like trying to execute undefined. It could also happen if you try to run array methods on an array-like object that isn't a true array. This also happens surprisingly often in React's JSX part when rendering lists.

When attempting to access properties of data types that cannot have properties, like null and undefined, a slightly different error message is displayed.

TypeError: Cannot read property ‘A’ of undefined
TypeError: Cannot read property ‘A’ of null

If the target is null or undefined, this message is shown not only when accessing data fields but also when trying to execute non-existent methods, instead of the ~ is not function error.

let mouse = null;

mouse.suspect; // TypeError: Cannot read property ‘suspect’ of null
mouse.end(); // TypeError: Cannot read property ‘end’ of null

When you encounter such messages, you'd typically search for the target property name to find out which variable holds the incorrect value. That variable will contain null or undefined. Tracing back to when that variable first received the incorrect value will likely lead to a quick solution.

Other TypeErrors are seen with roughly similar frequency. Perhaps one slightly more common error is the "is not a constructor" error.

TypeError: X is not a constructor

This error message appears when the variable X holds a non-constructor value, but you use the new keyword like new X(). This can occur in code that hides the constructor and provides an instance instead, such as in abstract factories or similar implementations. It's likely to be in lower-level structural code. Simple mistakes could include using a similarly named variable incorrectly or overwriting the variable holding the constructor with another value.

The general approach to solving TypeErrors is to find the location in the stack trace, check the value of the related variable, and then read the code backward to determine when it acquired the incorrect value. Alternatively, you could use a debugger starting from the variable's initialization point and step through to see how its value changes. Unless the error originates from an external dependency's code, you should be able to find the source location quickly. Even with external dependencies, tracing with a debugger isn't too difficult, although fixing it can be tricky. :)

SyntaxError

This error used to occur more frequently than TypeError. It happens when the JavaScript engine cannot understand the code because the syntax used is incorrect. In the days before static analysis tools, there was no way to know about typos made while writing code in the editor beforehand, so syntax errors were only discovered in the browser. Nowadays, tools like ESLint and Prettier warn or fix code at the time of writing, so these issues are resolved in the editor before even reaching the browser. If you use static analysis tools correctly, you'll rarely encounter this error, but let's introduce a few cases.

SyntaxError: Unexpected token

This error message was quite common until a few years ago. It occurs when a character that the JavaScript engine cannot understand is present in the code. This means there's a character that doesn't conform to the syntax rules. Even those familiar with JavaScript syntax can make mistakes or typos. For those who enjoy using vim or vim simulation modes, it can happen when the key sequence for escaping (e.g., "jk") is accidentally entered into the code. Similarly, mistyping shortcuts can also cause this. For example, frantically pressing Ctrl+S multiple times might insert the letter 's' into the code before saving. You've probably done this a few times, right? :)

In versions prior to IE 8, a trailing comma in an object literal was not recognized as valid code and caused an error.

var myObj = {
  a: ‘hi’,
  b: ‘hey’,   // error
}

Back when only IE6-7 existed, this happened occasionally due to mistakes but was quickly resolved. Ironically, I recall struggling with this a few times later, when life got easier (?) and build tools became common. There was an issue where a build tool generated trailing commas. The codebase didn't have them, but the build tool added them, causing problems in IE7 and below. I believe it was related to UglifyJS, specifically a minification issue. Even now, if I encounter that error in IE during cross-browser testing, the first thing I'd look for is a trailing comma. Thankfully, the need to test these older IE versions is diminishing. What a relief.

Syntax errors have become rare to see in the browser these days thanks to the use of static analysis tools like ESLint. Properly configuring and using ESLint along with Prettier in your editor is recommended. Prettier also has features that quite accurately report syntax errors when they occur.

RangeError

Next is the RangeError. These errors occur when a value or data exceeds the valid range of a resource. Basically, something is too large or invalid.

RangeError: invalid array length

This error is the easiest way to explain RangeError, but it's usually hard to encounter. It occurs when an array exceeds its maximum available size. According to the ECMA-262 specification, the valid maximum size for an array is 4,294,967,295, but this is known to differ depending on the browser or platform. If an array needs to be larger than the allowed size, you might need to create an array-like data structure that can handle multiple arrays as one, or perhaps use a library. I haven't searched, but useful libraries might already exist; the Node.js ecosystem has almost everything.

RangeError: invalid date (Edge)
RangeError: invalid date (Firefox)
RangeError: invalid time value (Chrome)
RangeError: Provided date is not in valid range (Chrome)

There are also errors like these that occur when creating Date objects with invalid values.

Among RangeErrors, the most famous one is probably the call stack size exceeded error.

Error: Out of stack space (Edge)
InternalError: too much recursion (Firefox)
RangeError: Maximum call stack size exceeded (Chrome)

This error occurs when the function call stack becomes too large. The error message and even the error type vary across browsers. IE used to display the same message as Chrome. Since Chrome is generally more convenient for development, Chrome's error type is often used as the standard reference. This was an error message frequently encountered during the era when IE6 support was required. Back then, it even occurred often in production services, whether developers knew about it and couldn't fix it, or simply didn't know, is unclear.

The call stack can be thought of as one of the components used within the JavaScript engine. When a function executes, the running function is added to the call stack list. If another function is called within that function, it too is added to the call stack. If the same function is repeatedly called, this constitutes recursion. Due to the stack data structure, the most recently executed function is at the top, and the first executed function is at the bottom. When a function finishes execution, it is removed from the top of the call stack one by one, returning to the context of the previous function. A call stack exceeded error means that functions were continuously called within other functions, piling up on the call stack, but they didn't terminate properly and kept accumulating, causing the call stack to exceed the system's allowed size. This problem often arises in recursive calls, and tail call optimization (TCO) was introduced to address it. In JavaScript environments supporting ES6, TCO can be implemented by using arguments instead of return values (Tail call optimization in ECMAScript 6).

This error is often caused by bugs in the exit logic of recursive code. While creating recursive calls during front-end development is relatively rare, it might occur in algorithm-level code or code that traverses text or data structures. In any case, when this problem occurs, it's typically resolved by finding the recursive code and examining the exit condition. Sometimes, you might encounter this even in well-established modern framework environments; although the specific code varies, it can sometimes happen when a setter sets a value with the same data it already holds. Care must also be taken when creating properties using the set and get keywords in vanilla JavaScript.

Conclusion

We've looked into TypeError, SyntaxError, and RangeError types. Besides these, according to MDN, there are also EvalError, ReferenceError, URIError, AggregateError, and InternalError. This post focused on summarizing the frequently occurring errors among these.

If you ever encounter an unusual error message and feel flustered, MDN has good explanations for various error messages. Referring to it should be helpful.

♥ Support writer ♥
with kakaopay

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

shiren • © 2025Sungho Kim