UnboundLocalError: cannot access local variable 'total' where it is not associated with a value

Python · updated 2026-11-04

Raised when a function reads a name that Python treats as local (because the function assigns it somewhere) before any assignment has run. Older versions say "local variable 'x' referenced before assignment".

Traceback (most recent call last):
  File "/app/billing.py", line 30, in <module>
    print(invoice_total(lines))
  File "/app/billing.py", line 14, in invoice_total
    return total
           ^^^^^
UnboundLocalError: cannot access local variable 'total' where it is not associated with a value

Quick fix

Assign the variable before any branch that might skip it (total = 0 at the top), or make sure every if/elif/else and try/except path sets it. If you meant a module-level variable, pass it in as an argument instead of assigning to it inside the function.

  1. Find every place the function assigns the name; the read happens on a path where none of them ran.
  2. Initialize it at the top of the function with a sensible default.
  3. For try/except, set it before the try, or handle the except path explicitly.
  4. If the function assigns to a module-level name, Python treats it as local everywhere in that function: rename it, or pass and return the value.
python
def invoice_total(lines):
    total = 0                      # before: assigned only inside the loop
    for line in lines:
        total += line.qty * line.price
    return total                   # safe even when lines is empty

def load_config(path):
    config = {}                    # before: set only in the try block
    try:
        config = read_json(path)
    except FileNotFoundError:
        log.warning("no config at %s, using defaults", path)
    return config

Why it happens

Assigned only inside a loop or branch

A variable set inside a for loop or an if block is unset when the loop has no items or the condition is false.

Assigned inside try, read after except

When the try block fails before the assignment and the except block does not set it, the code after the try reads an unset variable.

Shadowing a module-level name

count += 1 inside a function makes count local for the whole function, so reading it first fails even though a module-level count exists.

Other fixes

  • Linters (pyright, pylint "possibly-used-before-assignment") catch most of these before the code runs.
  • Use global or nonlocal only when you really intend to change an outer variable; passing values is usually clearer.

Same error, other wording

  • UnboundLocalError: local variable 'total' referenced before assignment
  • UnboundLocalError: cannot access local variable 'response' where it is not associated with a value
  • NameError: free variable 'x' referenced before assignment in enclosing scope

Let your coding agent catch the next one

Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:

> Find the UnboundLocalError exceptions in production, show me each variable and the code path where it was never assigned, and initialize it or handle that path.

Plans from $29/moSee what your agent readsSee the setupCancel any time from the billing portal

Related errors

References: Python docs: built-in exceptions (UnboundLocalError), Python FAQ: why do I get an UnboundLocalError