reflex-dev/reflex · error · UntrackedLocalVarError
{local_name!r} is not tracked in the current scope.
Error message
{local_name!r} is not tracked in the current scope. What it means
The dependency tracker walks bytecode and only understands locals it has recorded (function args, assignments, comprehensions). Accessing a local name it never tracked raises UntrackedLocalVarError.
Source
Thrown at packages/reflex-base/src/reflex_base/vars/dep_tracking.py:146
def get_tracked_local(self, local_name: str) -> type[BaseState] | ModuleType:
"""Get the value of a local name tracked in the current function scope.
Args:
local_name: The name of the local variable to fetch.
Returns:
The value of local name tracked in the current scope (a referenced
BaseState subclass or imported module).
Raises:
UntrackedLocalVarError: If the local variable is not being tracked.
"""
try:
local_value = self.tracked_locals[local_name]
except KeyError as ke:
msg = f"{local_name!r} is not tracked in the current scope."
raise UntrackedLocalVarError(msg) from ke
return local_value
def load_attr_or_method(self, instruction: dis.Instruction) -> None:
"""Handle loading an attribute or method from the object on top of the stack.
This method directly tracks attributes and recursively merges
dependencies from analyzing the dependencies of any methods called.
Args:
instruction: The dis instruction to process.
Raises:
VarValueError: if the attribute is an disallowed name or attribute
does not reference a BaseState.
"""
from .base import ComputedVar
if instruction.argval in self.INVALID_NAMES:View on GitHub (pinned to 45b8ed5ab7)
Solutions
- Simplify the computed var: reference state attributes directly (self.other.value) so tracking works
- Move complex logic into a plain (non-cached, non-tracked) helper and pass explicit values
- Explicitly declare deps=[...] so automatic tracking is not required
- Report the pattern upstream if it looks like valid code the tracker should support
Example fix
# before
@rx.memo
def full(self):
name = format_name(self.first, self.last) # helper confuses tracker
return name
# after
@rx.memo
def full(self):
return f"{self.first} {self.last}" Defensive patterns
Strategy: fallback
Try / catch
from reflex.vars.dep_tracking import UntrackedLocalVarError
try:
@rx.memo
def v(self): return complex_helper(self.a, self.b)
except UntrackedLocalVarError:
@rx.memo(deps=[State.a, State.b])
def v(self): return complex_helper(self.a, self.b) Prevention
- Keep cached computed vars simple: direct self.attr references
- Declare deps explicitly when logic is complex
- Avoid closures/walrus/exotic patterns inside tracked functions
When it happens
Trigger: A cached computed var that references a closure variable, imported symbol used as a local, or an exotic bytecode pattern the tracker does not model, then calls get_tracked_local for that name.
Common situations: Cached computed vars using complex helpers, lambdas, walrus edge cases, or language features newer than the tracker supports.
Related errors
- Cannot determine dependencies in fetched state {local_name!r
- Cached var {self!s} cannot access arbitrary state via `{inst
- UntypedComputedVarError(var_name=fget.__name__)
- Unexpected keyword arguments: {tuple(kwargs)}
- ComputedVar dependencies must be Var instances or var names
AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28).
Data as JSON: /api/errors/e521ffd94f031ce8.
Report an issue: GitHub.