{"record":{"id":"812cda5c17c10aec","repo":"reflex-dev/reflex","slug":"background-task-must-use-async-with-self-to-modi","errorCode":null,"errorMessage":"Background task must use `async with self` to modify state.","messagePattern":"Background task must use `async with self` to modify state\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"reflex/istate/proxy.py","lineNumber":210,"sourceCode":"                if self._self_mutable and self._self_actx is not None:\n                    await self._self_actx.__aexit__(*exc_info)\n            finally:\n                self._self_actx = None\n                self._self_mutable = False\n                self._self_actx_lock_holder = None\n                self._self_actx_lock.release()\n\n    def __enter__(self):\n        \"\"\"Enter the regular context manager protocol.\n\n        This is not supported for background tasks, and exists only to raise a more useful exception\n        when the StateProxy is used incorrectly.\n\n        Raises:\n            TypeError: always, because only async contextmanager protocol is supported.\n        \"\"\"\n        msg = \"Background task must use `async with self` to modify state.\"\n        raise TypeError(msg)\n\n    def __exit__(self, *exc_info: Any) -> None:\n        \"\"\"Exit the regular context manager protocol.\n\n        Args:\n            exc_info: The exception info tuple.\n        \"\"\"\n\n    def __getattr__(self, name: str) -> Any:\n        \"\"\"Get the attribute from the underlying state instance.\n\n        Args:\n            name: The name of the attribute.\n\n        Returns:\n            The value of the attribute.\n\n        Raises:","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/reflex-dev/reflex/blob/45b8ed5ab735f8a56bbb09a42384f030eb0208e7/reflex/istate/proxy.py#L192-L228","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\n@rx.event(background=True)\nasync def handler(self):\n    with self:\n        self.count += 1\n\n# after\n@rx.event(background=True)\nasync def handler(self):\n    async with self:\n        self.count += 1","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["reflex","background-task","sync-vs-async","api-misuse"],"backgroundTag":"sync-context-on-async-object","analyzedSha":"45b8ed5ab735f8a56bbb09a42384f030eb0208e7","analyzedAt":"2026-08-28T19:25:27.644Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}