UnboundLocalError
Any assignment to a name anywhere in a function makes it local for the whole function — so reading it before that assignment runs fails, even if a global of the same name exists.
Demo
def label(n): if n > 0: kind = 'positive' return kind label(5)
In Trigger, a positive n works and 0 fails: kind is a local of label (it is assigned there), so Python never falls back to a global — it just finds the local empty. The message names the variable but not the reason; look for the paths where no assignment ran. Handle shows the other classic case fixed: without global count, count += step would raise the same error on every call.
Constructor
| Name | Type | Required | Description |
|---|---|---|---|
| *args | object | no | Usually one message string. Unlike NameError, e.name is not filled in (it stays None). |
Attributes
| Attribute | Type | Meaning |
|---|---|---|
| args | tuple | args[0] is the message, e.g. "cannot access local variable 'x' where it is not associated with a value". |
| name | None | Inherited from NameError but not set for UnboundLocalError — parse args[0] if you need the variable name. |
Common patterns
def label(n): kind = 'non-positive' if n > 0: kind = 'positive' return kind
def make_counter(): n = 0 def inc(): nonlocal n n += 1 return n return inc
def bump(count, step): return count + step count = bump(count, 1)
Examples
Pitfalls
count = 10 def bump(step): count += step return count bump(1)
count = 10 def bump(step): global count count += step return count bump(1)
def make_counter(): n = 0 def inc(): n += 1 return n return inc make_counter()()
def make_counter(): n = 0 def inc(): nonlocal n n += 1 return n return inc c = make_counter() c() c()
def f(): len = len([1, 2]) return len f()
def f(): size = len([1, 2]) return size f()
When to use
- You rarely catch it — it signals a scoping bug to fix
- except NameError already covers it when probing names dynamically
- Updating module state → global x (or better, return the new value)
- Updating closure state → nonlocal x
- Maybe-assigned locals → initialise before the if/try/for
Notes
FAQ
The function assigns to that name somewhere, which makes it a local variable for the whole function body. At the moment the read ran, no assignment had happened yet — either it comes later in the code, or it sits in an if, try or loop body that did not run. Python does not fall back to a global of the same name.