Main Ecosystems
HomePython CorePandas ReferenceNumPy ScientificFastAPI & PydanticDjango Enterprise
More Ecosystems
Environment & SetupRequests & HTTPAsyncIO ConcurrencyObject-Oriented OOPPyTorch Deep LearningScikit-Learn MLFlask FrameworkWeb ScrapingDatabase & ORMDevOps & Docker

UnboundLocalError: cannot access local variable where it is not associated with a value in Python

Verified FixPython 3.10+Python NativeSilo: core

Quick Fix / Solution Rapide

Initialize the variable locally before conditional branches, pass it as a function parameter, or declare global var_name / nonlocal var_name if modifying outer scope variables.

Root Cause Analysis

This error occurs when Python tries to read a variable inside a function body, but Python's compiler classified that variable as local to the function because an assignment (=, +=, or :=) exists somewhere in the function scope, and the read operation occurred before the assignment was reached.

Python's LEGB Scope and Compile-Time Variable Binding

Python determines variable scope at compile time (when the function is defined), not at runtime. The rule is simple:

If a variable is assigned anywhere inside a function, Python marks it as a local variable for the entire function body.

Consider this classic trap:

count = 10
def increment():
    count += 1  # count = count + 1

Because count = ... exists on the right side of +=, Python treats count as purely local. When it evaluates the left side count + 1, the local variable has not yet been bound to any value, raising UnboundLocalError: cannot access local variable 'count' where it is not associated with a value.

Common Scenarios

  • Conditional Initialization: Reading result after an if condition: block where the else: branch was omitted.
  • Modifying Global Counters: Calling counter += 1 inside helper functions without global counter.
  • Closures & Nested Functions: Reassigning outer variables in inner functions without nonlocal.

Reproduction Code (MCVE)

Example: Bug Reproduction
counter = 10

# Python marks 'counter' as local due to the assignment inside the conditional branch
def calculate(flag: bool = False):
    if flag:
        counter = 20
    print(counter)  # Reading unbound local variable raises UnboundLocalError

calculate()

Solution 1: Explicitly Initialize Local Variable or Pass as Argument

Pass values explicitly as function arguments or initialize default fallback values at the top of the function.

Example: Recommended Solution
def calculate_safe(base_val: int = 10, flag: bool = False) -> int:
    # Initialize locally at function entry point
    result = base_val
    if flag:
        result = 20
    return result

print(f'Default execution: {calculate_safe()}')
print(f'Flagged execution: {calculate_safe(flag=True)}')

Solution 2: Use `global` or `nonlocal` for State Modification

Use global for module-level variables or nonlocal for enclosing closure scopes.

Example: Alternative Solution
def create_counter():
    count = 0
    def increment():
        nonlocal count  # Declares count belongs to outer enclosing scope
        count += 1
        return count
    return increment

counter_fn = create_counter()
print(f'Counter step 1: {counter_fn()}')
print(f'Counter step 2: {counter_fn()}')

Common Pitfalls & Error Contrasts

Contrasting UnboundLocalError with NameError:

  • UnboundLocalError: Subclass of NameError. The variable was detected as a local symbol by the compiler, but was read before assignment.
  • NameError: name 'x' is not defined: The symbol does not exist in any scope (Local, Enclosing, Global, or Builtin).
  • Shadowing: Naming a local variable the same as a built-in (e.g. list = [1, 2]) shadows the built-in function throughout the scope.