🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

Python's NameError Isn't Scary! A Thorough Guide to the "Variable Not Defined" Error for Beginners

When you're just starting to learn programming, seeing error messages in red text can feel like they're saying, "You can't do this," and it's easy to get discouraged, right? To be honest, just a few months ago, I had zero programming knowledge and spent my days staring at error screens.

One of the first walls that beginners often hit is the `NameError: name '...' is not defined` error.

But don't worry. This error isn't difficult at all. In fact, it's just Python's way of kindly telling you, "Sorry, I don't know the name '...' you just mentioned."

In this article, as someone who single-handedly launched two websites in a month and a half with the help of AI, I will explain the cause and solution for `NameError` from the exact same "beginner's perspective" as you, thoroughly and more clearly than anywhere else. I won't use technical jargon. With concrete examples of where I actually stumbled, I promise that by the time you finish reading this article, you'll be able to solve `NameError` on your own.

And most importantly, I've prepared a lot of code that you can just copy and paste to experience it "working!" Let's rediscover the joy of programming together by experiencing the satisfaction of solving errors!


What is a NameError Anyway? - A Sign from Python Saying "I Don't Know That!"

First, let's see when a `NameError` occurs with a simple piece of code. This is an error where Python is telling you, "I don't know that name." Your program remembers the variable and function names you write, but if it's called by a name it doesn't remember, it gets confused and thinks, "Wait, who's that?" That's the essence of a `NameError`.

For example, let's say you run the following code.


# Trying to display a greeting message
print(message)
            

If you run this, you will 100% get this error.


Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'message' is not defined
            

`NameError: name 'message' is not defined` literally means what it says. In other words, Python was told to display something called `message` with `print()`, but since it was never told what `message` is (it was not defined), it raised an error and stopped the process.

The error message (Traceback) is a crucial hint that tells you where the problem is. `File "<stdin>", line 1` means "the error occurred on line 1." Let's use this hint to find the cause.


[By Cause] The 3 Main Cases of NameError and Their Solutions

Most of the `NameError`s I've encountered were caused by one of the following three reasons. Let's go through them one by one, with specific stories of my failures and copy-paste-ready corrected code.

Case 1: Simple Typos (Spelling Mistakes)

This is the most common cause, and perhaps the hardest to spot. I once spent 30 minutes wondering why my code wasn't working, only to find I had written "`mesage`" instead of "`message`". Python recognizes variable and function names as completely different things if even a single character is off.

❌ Bad Example (Causes NameError)

We define a variable `greeting` and try to print it, but we've made a typo (`greting`) inside the `print()` function.


# Store a greeting in a variable called "greeting"
greeting = "Hello, World!"

# A typo when trying to print it!
print(greting) # <- Missing one 'g'!
            

Error Result:

NameError: name 'greting' is not defined

✅ Good Example (Works Correctly)

Correct the typo and call the `print()` function with the same name as the defined variable, `greeting`. Just by doing this, the error magically disappears.


# Store a greeting in a variable called "greeting"
greeting = "Hello, World!"

# Print it using the correct variable name
print(greeting)
            

Execution Result:

Hello, World!

[Troubleshooting Tip] When you get a `NameError`, first carefully compare the name shown in the error message (like `'greting'`) with the variable name you intended to define (`greeting`), character by character, to check for typos.


Case 2: Using a Variable Before Defining It

A program is basically executed sequentially from top to bottom. It's like a cooking recipe. Even if "sprinkle salt" is the first step in the recipe, if you haven't completed the "prepare the chicken" step before it, you won't know what to sprinkle salt on. Python is the same; you'll get a `NameError` if you try to use a variable before assigning a value to it (defining it).

❌ Bad Example (Causes NameError)

We are trying to print the user's name, `user_name`, but the line that actually assigns a name to `user_name` comes after it.


# Trying to print the variable before we know what's in it
print(user_name)

# Assigning a name to the variable after trying to print it
user_name = "Suzuki"
            

Error Result:

NameError: name 'user_name' is not defined

✅ Good Example (Works Correctly)

Correct the order of operations. First, assign (define) the string "Suzuki" to `user_name`, and then call `print()` to display it.


# First, assign a name to the variable (define it)
user_name = "Suzuki"

# After defining it, display the variable
print(user_name)
            

Execution Result:

Suzuki

[Troubleshooting Tip] If you get a `NameError`, check if the variable has been properly defined in a line above the line where the error occurred. Tracing the program flow with your finger from top to bottom can also be effective.


Case 3: The "Scope" Wall - Using a Variable Outside Its Reach

This is a slightly more advanced topic, but it's a major pitfall for beginners. "Scope" simply refers to the "effective range of a variable." I often call it the "variable's room."

A variable defined inside a function (a local variable) can only be used within that function's room. If you try to use that variable from outside the function, Python will return a `NameError`, saying, "There's no variable with that name in this room (the global scope)."

❌ Bad Example (Causes NameError)

A variable `local_msg` is defined inside the function `create_message`. This variable is only valid inside the `create_message` room. However, we are trying to call it from outside the function (outside the room) with `print(local_msg)`, which causes an error.


def create_message():
    # This variable is only valid inside the "room" of the create_message() function
    local_msg = "This is a local message"
    print("Visible from inside the function:", local_msg)

# Execute the function
create_message()

# Trying to use the variable from outside the function's "room"
print(local_msg) # <- Error here!
            

Error Result:

Visible from inside the function: This is a local message
Traceback (most recent call last):
  File "<stdin>", line 9, in <module>
NameError: name 'local_msg' is not defined

The first `print` succeeds, but we can see that the error occurs on line 9.


✅ Good Example (Works Correctly)

If you want to use a value from inside a function's room on the outside, you need to use `return` to pass it out as the function's "return value." Imagine the function returns a value, and you catch it with a new variable.


def create_message():
    # This variable is only valid inside the "room" of the create_message() function
    local_msg = "This is a message to be passed outside"
    # Use return to pass the variable's "value" outside the function
    return local_msg

# Execute the function and receive the return value in a variable called message_from_func
message_from_func = create_message()

# Display the received variable
print(message_from_func)
            

Execution Result:

This is a message to be passed outside

[Troubleshooting Tip] The standard way to use a value created inside a function on the outside is to return it with `return`. While there is a way to modify a variable outside a function from within using the `global` keyword, it tends to make programs more complex. Therefore, it's recommended to master how to use `return` first. This topic is also explained in detail on the official Python website as the rules for local and global variables.


Debugging with AI! A Practical Technique to Solve NameErrors at Lightning Speed

You want to spend less time worrying about solving errors and more time on creative work, right? In such times, your best companion is an AI (like ChatGPT or Gemini).

Nowadays, whenever I encounter a `NameError`, I always follow these steps to ask for AI's help:

  1. Copy the entire error message: Select and copy all the error information displayed in the terminal, from `Traceback` to `NameError: ...`.
  2. Paste it and ask the AI: Open the AI's chat window, ask "Please explain the cause of this Python error in a way a beginner can understand," and paste the copied error message.
  3. Review your code based on the AI's answer: In most cases, the AI will pinpoint the exact cause, saying something like, "The variable '...' is not defined. It's likely a typo or you're calling it before it's defined."

Just the other day, I got a `NameError` in a code that calls a dictionary key, and I couldn't figure out the cause on my own. But when I threw the entire code and the error at an AI, it instantly told me, "When calling a dictionary key, you need to enclose it in quotes like `'key_name'`, but you are trying to call it as a variable without quotes, which is causing the `NameError`."

By utilizing AI as a debugging partner like this, you can dramatically reduce the time it takes to find a solution. Don't be afraid of errors; feel free to rely on AI more and more.


3 Good Habits to Prevent NameErrors Before They Happen

The ability to solve errors is important, but ideally, you want to write code that doesn't produce errors in the first place. Here are three habits I practice to reduce `NameError`s.

1. Use descriptive variable names
Short names like `x` or `tmp` are prone to typos and make it hard to remember what the variable is for when you look back at the code later. I strongly recommend using meaningful names like `user_name` or `total_price`, even if they are a bit longer.
2. Use a Linter
A linter is a tool that points out grammatical mistakes and potential bugs in your code in real-time as you write it. Advanced editors like VSCode allow you to easily add Python linters such as `Pylint` or `Flake8`. If you try to use an undefined variable, the editor will notify you with a wavy line or similar indicator before you even run the code, which can dramatically reduce `NameError`s.
3. Run your code frequently
If you run your code for the first time after writing 100 lines, it can be very difficult to find where the error is. If you get into the habit of checking your work in small increments—running the code after writing a few lines, or after creating a single function—it becomes much easier to pinpoint the location of an error.

Conclusion: Errors Are a Sign of Growth!

In this article, I've explained the causes and specific solutions for `NameError`, a rite of passage for every beginner, sharing my own experiences along the way.

Let's review the three major causes of `NameError` one more time:

  • Typos: The spelling of a variable or function name is incorrect.
  • Incorrect execution order: Trying to use a variable before it has been defined.
  • The scope wall: Accessing a variable from outside its valid range, such as trying to use a variable from inside a function on the outside.

Error messages are valuable hints for getting your code to run. When you get a `NameError`, just think, "Ah, Python is telling me it doesn't know a name," and calmly look for the cause. And don't forget that you have a powerful companion in AI when you're stuck.

Every time you overcome an error, your programming skills are definitely improving. Errors are not something to be afraid of; they are the best teachers that help you grow. Let's continue to enjoy programming together!

To the Next Step

Once you've mastered `NameError`, why not learn about the next common error, `TypeError`? I provide an equally easy-to-understand explanation of how to solve errors caused by differences in data types, such as when you try to add a number and a string.

➡️ Proceed to How to Handle TypeError (Error for Mismatched Types)