Keras UnboundLocalError local variable 'logs' 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
When Keras raises UnboundLocalError for logs, the training loop usually reached callback code that expected a value that was never initialized. This often happens in custom callbacks, custom training loops, or version-mismatched examples copied from older APIs. The fix is to treat callback arguments defensively and ensure your code can run even when metrics are missing.
Why This Error Happens in Keras
The error message means Python saw a local variable named logs, but that variable was read before assignment in the same scope. In Keras callback methods like on_epoch_end, logs can be None or missing keys. If your code writes conditional assignments and then reads logs later, Python can fail before the training step is complete.
A common bad pattern is assigning logs inside one branch and using it outside the branch. Another issue is shadowing the callback argument with a local variable named logs. The callback method already provides the argument, so creating a second local variable with the same name can cause confusion and runtime errors.
The safe pattern is to normalize logs immediately and never assume keys exist.
Build a Safe Custom Callback
Initialize logs to an empty dictionary as soon as the callback starts. Then use .get for optional metrics. This keeps the callback stable even if metric names change, if validation is disabled, or if custom training code skips a metric in one epoch.
This script runs end to end and avoids the UnboundLocalError pattern because every path defines the variables before use.
Debugging Version and API Mismatch
Keras examples on older blogs can use callback behavior from earlier TensorFlow releases. Before copying code, print versions and verify metric names that appear in logs. It is common to expect acc while modern builds emit accuracy.
Using an inspection callback once during development helps you lock in the exact metric keys and avoid fragile callback code.
Common Pitfalls
- Reusing the name
logsfor a new local variable and accidentally hiding the callback argument. - Assuming
logsis always populated even when a run is interrupted or configured with minimal metrics. - Reading
logs["val_loss"]when no validation data is passed tofit. - Copying examples that rely on deprecated metric names such as
accwithout checking current output. - Catching broad exceptions around callbacks, which hides the real control-flow error and makes debugging harder.
Summary
UnboundLocalErrorforlogsis a Python scoping issue, not a Keras math issue.- Normalize callback input with
logs = logs or {}at the start of each method. - Use
.getand key checks instead of direct indexing for optional metrics. - Verify TensorFlow version and inspect emitted metric keys before finalizing callback code.
- Keep callback logic simple and explicit so every execution path initializes needed variables.

