What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
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
UnboundLocalError means Python treats a name as local to a function, but the function tries to use it before assigning a value to that local name. A global or enclosing variable with the same name does not fill in the local value: assignment anywhere in the function makes the name local throughout that function unless it is declared global or nonlocal.
Why Python raises UnboundLocalError
Python determines a function’s local names from the bindings in the whole function body, not just the statements that have run so far. If a name is assigned anywhere in a function, Python treats references to that name in the function as references to its local binding. If execution reaches a reference before that local has a value, Python raises UnboundLocalError.
For example, the module-level x below has a value, but it is not used by foo:
x = 10
def foo():
print(x)
x += 1
The augmented assignment x += 1 binds x locally in foo. That local binding shadows the module-level name, so print(x) tries to read a local value that has not yet been assigned. The Python FAQ explains this rule and demonstrates the example in its UnboundLocalError answer.
#1 Best Overall
The same rule applies when an assignment appears only in one branch. If another path reaches a read without first executing that assignment, the local name has no value on that path. A loop or exception-handling path can create the same problem if it reads a local before the relevant assignment has run.
What to check in the traceback and function
- Read the complete traceback and note the function and variable named in the final error line.
- In that function, find every operation that binds the name: ordinary assignment, augmented assignment such as
+=, and assignments inside branches or other control-flow blocks. - Check the order of execution on the failing path. Ask whether every route to the failing read passes through an assignment first.
- Decide where the value is meant to live: in this function, at module scope, in an enclosing function, or as data passed into or out of the function.
- Make the smallest fix that matches that ownership, then test the failing path and paths that skip conditional assignments.
For interactive diagnosis, Python’s FAQ points to breakpoint(), pdb, and IDLE’s graphical debugger. It also names Visual Studio Code, Wing IDE, and PyCharm as IDEs with debuggers. For static checks, it lists Ruff, Pylint, and Pyflakes. These are optional ways to inspect code; the scope rule itself is the cause.
Rank #2
Choose a fix based on where the value belongs
| Intended ownership | Fix | Effect |
|---|---|---|
| Local to this function | Assign an initial value before any possible read, on every relevant path. | Keeps the state within the function. |
| Module-level binding | Declare global name in the function before using or assigning that name. |
Allows the function to rebind the module-level name. |
| Binding in an enclosing function | Declare nonlocal name in the nested function before rebinding it. |
Allows the nested function to rebind an existing name in an enclosing function scope. |
| Value should flow between functions | Pass it as a parameter, return an updated value, or restructure the function around an explicit local. | Makes inputs and outputs explicit rather than changing outer-scope state. |
Keep the value local
If the function owns the value, initialize it before its first possible read. Check branches, early returns, loops, and exception paths; placing an assignment somewhere in the function is not enough if the failing path can skip it.
Free tools Windows power users keep installed
One-click scans. No signup required.
Use global only for deliberate module rebinding
Declare global x inside the function when the function is meant to rebind the module-level x. The Python FAQ shows this as a direct fix for its example. Because it changes which binding the function writes to, do not add it merely to silence the exception.
Use nonlocal for deliberate enclosing-scope rebinding
In a nested function, declare nonlocal name when the intent is to rebind a name in an enclosing function scope. It is not a declaration for module-level variables; use global for those.
Prefer explicit data flow when outer mutation is unnecessary
If the function does not need to modify outer state, pass the needed value in or return the result. This avoids introducing shared rebinding when a local calculation or an explicit input/output better expresses the program’s design.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.What the error message tells you
UnboundLocalError is a subclass of NameError. The wording depends on Python version: Python 3.14.7’s FAQ example says cannot access local variable 'x' where it is not associated with a value, while older documentation uses wording such as local variable 'x' referenced before assignment. The phrasing can vary; the underlying issue is a local binding read before it has a value. See the Python execution model and built-in exception reference.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Quick Recap
Best Value
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.

