reflex-dev/reflex · error · TypeError
Background task must use `async with self` to modify state.
Error message
Background task must use `async with self` to modify state.
What it means
The StateProxy returned in background tasks only supports the async context manager protocol for acquiring mutability; `with self:` (sync) cannot await the underlying lock, so __enter__ unconditionally raises TypeError telling you to use `async with self`. This is a hard API guard: there is no sync path.
Source
Thrown at reflex/istate/proxy.py:210
if self._self_mutable and self._self_actx is not None:
await self._self_actx.__aexit__(*exc_info)
finally:
self._self_actx = None
self._self_mutable = False
self._self_actx_lock_holder = None
self._self_actx_lock.release()
def __enter__(self):
"""Enter the regular context manager protocol.
This is not supported for background tasks, and exists only to raise a more useful exception
when the StateProxy is used incorrectly.
Raises:
TypeError: always, because only async contextmanager protocol is supported.
"""
msg = "Background task must use `async with self` to modify state."
raise TypeError(msg)
def __exit__(self, *exc_info: Any) -> None:
"""Exit the regular context manager protocol.
Args:
exc_info: The exception info tuple.
"""
def __getattr__(self, name: str) -> Any:
"""Get the attribute from the underlying state instance.
Args:
name: The name of the attribute.
Returns:
The value of the attribute.
Raises:View on GitHub (pinned to 45b8ed5ab7)
Solutions
- Change `with self:` to `async with self:` in background event handlers
- Ensure the enclosing handler is async (@rx.event(background=True) handlers are coroutines)
- Lint for `with self` inside async handlers (e.g. a custom ruff/pylint rule) if this recurs
Example fix
# before
@rx.event(background=True)
async def handler(self):
with self:
self.count += 1
# after
@rx.event(background=True)
async def handler(self):
async with self:
self.count += 1 Defensive patterns
Strategy: validation
Prevention
- Always write `async with self:` in background handlers
- Make handlers async so the sync form is never tempting
- Add a lint rule grepping for `with self` in async functions
When it happens
Trigger: Writing `with self:` instead of `async with self:` inside an @rx.event(background=True) handler. Often a typo or muscle memory from sync code / older Reflex examples.
Common situations: Converting normal event handlers to background tasks and forgetting to switch the context keyword; IDE autocompleting `with`; porting code from other frameworks with sync context managers.
Related errors
- Var-returning `@rx.memo` `{func_name}` cannot depend on hook
- @rx.event(background=True) is required for upload_files_chun
- Do not override _add_style directly. Use add_style instead.
- Only one of `data` or `fp` may be provided, not both.
- At least one of `data` or `fp` must be provided.
AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28).
Data as JSON: /api/errors/812cda5c17c10aec.
Report an issue: GitHub.