UnboundLocalError local variable 'batch_outputs' referenced before assignment
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
UnboundLocalError: local variable 'x' referenced before assignment occurs when Python detects that a variable is assigned somewhere in a function and therefore treats it as local for the entire function, even before the assignment line executes. If you try to read the variable before the assignment (often because the assignment is inside an if block that did not execute), Python raises this error instead of looking at the outer scope. The fix depends on whether you intended to use a local or global variable.
The Error
Python sees batch_outputs = transform(data) and marks batch_outputs as a local variable for the entire function. When data is empty, the assignment never runs, but the return still tries to read the local (unset) variable.
Why Python Does This
Python determines variable scope at compile time, not runtime. If a variable name appears on the left side of an assignment anywhere in a function, it is local to the entire function:
Even though print(x) comes before x = 20, Python has already decided that x is local based on the assignment. The print tries to read local x before it has been assigned.
Fix 1: Initialize the Variable Before the Condition
This ensures batch_outputs is always assigned before it is read, regardless of which branch executes.
Fix 2: Use the global Keyword
If you intend to modify a module-level variable:
global tells Python to use the module-level batch_outputs instead of creating a local one. Use this sparingly — global mutable state makes code harder to test and debug.
Fix 3: Use the nonlocal Keyword (Nested Functions)
For variables in an enclosing function scope:
nonlocal tells Python that count belongs to the enclosing scope, not the local scope. Without it, count += 1 (which is count = count + 1) makes count local, and reading count on the right side fails.
Fix 4: Use a Return Value Instead of Mutation
Common Patterns That Trigger This Error
Augmented Assignment on Global
Loop Variable Leaking Expectation
Try/Except Variable Scope
How to Debug
Common Pitfalls
- Assignment inside
if/try/forblocks: Variables assigned inside conditional blocks are still local to the function, but they may not be assigned if the block does not execute. Always initialize before the block. globaloveruse: Usingglobaleverywhere to avoid the error introduces shared mutable state. Prefer passing values as arguments and returning results.- Augmented assignment (
+=,-=):x += 1isx = x + 1— it both reads and writes. Ifxis not local yet, the read fails. Useglobalornonlocalto reference the outer variable. - Variable name shadowing: Using the same name for a local and global variable is confusing. Rename the local variable to avoid ambiguity:
local_outputsinstead of reusingbatch_outputs. - Python 2 vs Python 3: Python 2 does not have
nonlocal. The workaround was using mutable containers:count = [0]; count[0] += 1(modifying the container does not create a new local).
Summary
UnboundLocalErrormeans Python treats a variable as local (because it is assigned somewhere in the function) but it was read before being assigned- Python determines scope at compile time based on the presence of assignments, not at runtime
- Initialize variables before conditional/try blocks to ensure they always have a value
- Use
globalfor module-level variables ornonlocalfor enclosing function variables - Prefer returning values over modifying outer-scope variables to avoid scope confusion

