The Most Misinterpreted Type of Programming Error Message for Newbies

debugging

Cross-posted from the official Kickstart Coding blog

The Errors

Here are three code snippets that produce three very similar error messages in three different languages:

In Python

The Code

person.register()

The Error

AttributeError: 'NoneType' object has no attribute 'register'

In JavaScript

The Code

person.register()

The Error

Uncaught TypeError: Cannot read property 'register' of undefined

In Ruby

The Code

person.register()

The Error

NoMethodError: undefined method 'register' for nil:NilClass

Okay, so…?

These errors all happen for the same reason. But it’s not the reason most newbie programmers think. The error messages all talk about register not existing, so programmers naturally assume that the problem has to do primarily with their register method not being defined. It sounds like register doesn’t exist, so they naturally look to make sure they’ve created a register method in their code.

They might imagine that the error is happening because their Person class looks something like this (using JavaScript in this example):

class Person {
  // Oops, no register method!
}

But when they go to check their code, that’s usually not the problem. The Person class is usually fine and the register method is usually present and accounted for.

class Person {
  register() {
    console.log("I really do exist! Honest!")  
  }
}

If you find yourself in this situation, it’s more likely that if you zoom out from person.register(), you’ll find some code that is supposed to put a value into the person variable, and that code is the true culprit. Let’s say, for example, you’ve got a function that searches for a person by their e-mail address and then returns that person if it can find them. The code might look something like this:

person = getPersonByEmail("some_email@some_website.com")

person.register()

In this example, the most likely real problem would be that getPersonByEmail is not finding a person. It has nothing whatsoever to do with a missing register method, in spite of what the error message would lead you to believe.

There are two pieces of information in each of these error messages. They tell you explicitly that register doesn’t exist. But they also tell you implicitly that person doesn’t exist.

‘NoneType’ object has no attribute ‘register’

Cannot read property ‘register’ of undefined

NoMethodError: undefined method ‘register’ for nil:NilClass

NoneType, undefined, and NilClass are the ways these three languages represent something that doesn’t exist. Nine times out of ten, when you see this error message, your implementation of the register method is fine. It’s your person variable that’s the problem. It should be an object representing a person, but instead it’s NoneType, undefined, NilClass, in other words, nothing.

There’s probably a perfectly fine register method written for the Person class. But there’s no register method written for a NoneType. There’s no register method written for undefined. And there’s no register method written on an instance of NilClass.

If you see this kind of error, then the most likely problem with your code is that person isn’t getting set to the right thing, like in our example where getPersonByEmail can’t find a person with the e-mail you gave it. If getPersonByEmail can’t find a match, person doesn’t get set to anything at all. And because it isn’t set to anything, when you try to call register on it, you get a “register doesn’t exist” message because register exists for Person objects, not for “nothing” objects.

Because of the way these error messages emphasize register not existing, it takes a while for newbies to learn to check on what’s going on with person in the rest of their code when this happens instead of automatically zooming in on register.