ValueError tf.function-decorated function tried to create variables on non-first call
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
This TensorFlow error means a function wrapped with @tf.function tried to create new variables after TensorFlow had already traced the function once. tf.function expects variables to exist consistently across calls, so variable creation must happen once up front, not dynamically on later executions.
Why the Error Happens
@tf.function traces Python code into a graph-like callable. During that process, TensorFlow needs the variable structure to stabilize. If a variable appears on the first call but a different path creates variables on a later call, tracing and execution become inconsistent.
A common bad pattern looks like this:
This creates a new Dense layer and therefore new variables inside the function body every time. TensorFlow rejects that pattern.
Create Variables Outside tf.function
The usual fix is to create layers, variables, or submodules once, then call them inside the traced function.
Now the variables belong to layer, which is created once outside f.
The Same Rule Applies to Custom Modules
If you are writing a custom class, create variables in __init__, build, or another one-time setup path, not conditionally in the traced call logic.
This is the stable pattern TensorFlow expects.
Why It Often Appears With Keras Layers
Keras layers lazily create weights on first use. That is fine as long as the layer object itself persists across calls. The error usually appears when developers instantiate the layer inside the tf.function body rather than on the surrounding object.
So the question is not only “where are the weights created” but also “does the layer instance survive across calls.”
Once you recognize that tf.function is tracing reusable computation rather than reinterpreting arbitrary Python state on every call, the restriction makes sense. TensorFlow needs the function's variable structure to stop changing underneath it.
Common Pitfalls
The biggest mistake is instantiating Dense, Conv2D, or Variable objects inside a @tf.function-decorated function.
Another mistake is creating variables conditionally based on input data or branching logic after the first trace.
A third mistake is blaming eager versus graph mode when the real issue is variable lifecycle and object ownership.
Summary
- '
@tf.functionexpects variable creation to happen once, not on later calls.' - Do not instantiate layers or variables inside a traced function body.
- Create state outside the function or in one-time object setup methods.
- Keras lazy weight creation is fine when the layer instance persists across calls.
- When this error appears, inspect where the variables are being created, not just where the function is called.

