Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A NameError: name 'x' is not defined means Python ran a line that uses the name x, searched the scopes visible from that line, and found no binding for it. The fix is almost always one of two things: the name is spelled differently from how it was created, or it was never created (or imported) in a scope the failing line can see. The steps below show how to find which case you have, and how to fix each one.

What the error is telling you

Python raises NameError when an unqualified name, meaning a bare identifier with no dot in front of it, cannot be resolved. The message includes the name Python could not find. According to the Python Language Reference (Python 3.14.8 edition), the rule is stated directly: “When a name is not found at all, a NameError exception is raised.”

A name becomes available only through a binding operation. The common ones are:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Assignment, such as total = 0
  • A function or class definition, such as def load(): or class Parser:
  • A parameter of a function, such as def f(price):
  • An import, such as import json or from math import sqrt
  • A loop variable, a with ... as target, or an except ... as target

If none of these has run for the name in a scope the failing line can reach, Python raises NameError. Names are case-sensitive, so Total and total are different names.

Read the traceback before you change anything

The traceback tells you where the failure happened. Work through it in this order:

  1. Read the last line first. It gives the exception type and the name, for example NameError: name 'total' is not defined.
  2. Scroll up to the last frame that points to your own file. Library frames above it are usually not the cause.
  3. Look at the marked source line in that frame and find the exact spelling of the unresolved name.
  4. Search your code for every place that name is assigned, defined, parameterised or imported. Compare the spelling character by character.
  5. Decide whether that binding runs before the failing line, and whether it lives in a scope the failing line can see.

Newer interpreters may add a “Did you mean” suggestion to the message. Treat it as a hint to check against your code, not as the fix. Suggestions depend on the Python version and on what names are in scope, so their presence or absence tells you little on its own.

Every cause and fix

1. Misspelled or inconsistent identifier

This is the most common cause. The name is created correctly but used with a different spelling, capitalisation, or underscore pattern.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
user_name = "Ada"
print(username)
# NameError: name 'username' is not defined

Fix: make the failing line and the binding use the same identifier. Your editor’s “find all references” or a project-wide search for the name will catch mismatches quickly. Check for user_name versus userName, a trailing character, or a plural s that was added in one place only.

2. The name was never assigned or defined

The code uses a value that nothing in the program has created. This often happens when a variable is set inside an if branch that did not run, or when a helper function was renamed and a call was missed.

if debug:
    level = 3
print(level)   # NameError if debug is False

Fix: bind the name on every path before it is used, usually by giving it a default value above the branch:

level = 0
if debug:
    level = 3
print(level)

If the name is a function or class, define it before the first call. In a script, a call placed above the def line fails with this error because the definition has not run yet.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

3. Missing import or wrong imported name

A module’s contents are not available until you import them. Importing the module does not make its functions appear as bare names.

import math
print(sqrt(16))   # NameError: name 'sqrt' is not defined

Fix: either use the qualified name or import the object directly:

import math
print(math.sqrt(16))

# or
from math import sqrt
print(sqrt(16))

Also check the alias. If you wrote import numpy as np, then numpy.array is not a valid reference, and np.array is required. Check that the module name itself is spelled correctly and that the package is installed in the interpreter you are running.

4. Scope mismatch

A name bound inside one function is local to that function. It is not visible to other functions, and it is not a module-level global just because it looks like one.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
def build():
    config = {"debug": True}

def run():
    print(config)   # NameError: name 'config' is not defined

Fix: choose one of these, depending on what you intend:

  • Pass the value as an argument (usually the cleanest option): def run(config):, then call run(build()).
  • Return it from the function that creates it, and assign the return value where it is needed.
  • Use a module-level global only when the function is meant to read or update shared state. Declare it inside the function with global counter before assigning to it.
  • Use nonlocal only for a name that is bound in an enclosing function, not at module level.

Class bodies are a frequent trap. A name defined directly in a class body is not visible to its methods as a bare name. Refer to it as self.name for instance data, or as ClassName.name for class data.

class Settings:
    timeout = 30
    def show(self):
        print(timeout)   # NameError
        print(self.timeout)   # works

The Python Language Reference describes scope resolution in detail, including class scopes, comprehensions and annotation scopes. Do not assume that a simple “local, then enclosing, then global, then built-in” rule covers every case without checking those sections.

5. Local variable read before assignment (UnboundLocalError)

This is the case that surprises most people. If a function contains any assignment to a name, Python treats every use of that name in the function as local, unless the function declares it global or nonlocal. Reading the name before the local receives a value does not fall back to the module-level variable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
count = 0
def bump():
    count += 1   # fails: count is local here
bump()

This raises UnboundLocalError, not a plain NameError. The Python Language Reference states that “UnboundLocalError is a subclass of NameError.” Exact wording varies by version. Recent releases report something like cannot access local variable 'count' where it is not associated with a value, while older ones say local variable 'count' referenced before assignment. Either way, the cause is the same.

Fix:

  • Declare the intent: add global count as the first line of bump() if you want to update the module-level value.
  • Or pass the value in and return the new one: def bump(count): return count + 1.

Because UnboundLocalError is a subclass of NameError, a handler written as except NameError will catch it too. That can hide a real logic bug, so catch it deliberately only when you have a reason.

6. Notebook or interactive execution order

In Jupyter notebooks and similar interactive sessions, a name exists only if the cell that defines it has run in the current kernel session. A cell that was run earlier, then deleted, or run in a previous session, can leave the name missing.

  • Restart the kernel and choose Run All, so cells execute from the top in order.
  • If you restarted the kernel, re-run the cell that defines the name before the cell that uses it.
  • Check the cell numbers in the left margin. A cell with a high execution number that appears above a low one is a sign that the notebook was edited out of order.

This is a practical explanation based on the rule that names must be bound before use. Notebook tools do not change the Python language rule, so a clean top-to-bottom run is the reliable test.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Quick diagnostic table

What you see Most likely cause Where to fix it
Name looks right but differs from its definition by one character Misspelling or inconsistent identifier The failing line or the binding
Name is set inside an if, loop or try that may not run Name never bound on this path Give it a default before the block
Module name works but the function does not Missing import or no qualified name Use module.name or import the object
Name defined in one function, used in another Scope mismatch Pass as argument or return it
Message says UnboundLocalError Local read before assignment Declare global/nonlocal or restructure
Works after a full run, fails after a restart or in a selected cell Notebook execution order Restart and run top to bottom

Version notes

  • The NameError.name attribute, which holds the unresolved name as a string, was added in Python 3.10. In older versions, parse the message text instead.
  • Interpreter suggestions such as “Did you mean” and the wording of UnboundLocalError messages depend on the Python release. Do not rely on the exact text when writing tests; check the exception type and name attribute where available.

A checklist to finish the fix

  • The failing line’s spelling matches the binding exactly.
  • The binding runs before the failing line on every code path.
  • The binding is in a scope the failing line can see, or is passed in as an argument.
  • Imported names are used either qualified or imported explicitly.
  • No function assigns a name that it also reads before assignment, unless global or nonlocal is declared.
  • In a notebook, a clean top-to-bottom run completes without this error.

If the error still appears after these checks, print the value of locals() or globals() just before the failing line. Those dictionaries show exactly which names exist at that point, and the gap usually becomes obvious.

“

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.