{"record":{"id":"dda016b9f0dee498","repo":"reflex-dev/reflex","slug":"context-is-already-attached-cannot-enter-context","errorCode":null,"errorMessage":"Context is already attached, cannot enter context manager.","messagePattern":"Context is already attached, cannot enter context manager\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"packages/reflex-base/src/reflex_base/context/base.py","lineNumber":64,"sourceCode":"\n    @classmethod\n    def reset(cls, token: Token[Self]) -> None:\n        \"\"\"Reset the context variable to a previous state.\n\n        Args:\n            token: The token to reset the context variable to.\n        \"\"\"\n        cls._context_var.reset(token)\n\n    def __enter__(self) -> Self:\n        \"\"\"Enter the context.\n\n        Returns:\n            This context instance.\n        \"\"\"\n        if self._attached_context_token.get(self) is not None:\n            msg = \"Context is already attached, cannot enter context manager.\"\n            raise RuntimeError(msg)\n        self._attached_context_token[self] = self._context_var.set(self)\n        return self\n\n    def __exit__(self, *exc_info):\n        \"\"\"Exit the context.\"\"\"\n        if (token := self._attached_context_token.pop(self, None)) is not None:\n            self._context_var.reset(token)\n\n    def ensure_context_attached(self):\n        \"\"\"Ensure that the context is attached to the current context variable.\n\n        Raises:\n            RuntimeError: If the context is not attached.\n        \"\"\"\n        if self._attached_context_token.get(self) is None:\n            msg = f\"{type(self).__name__} must be entered before calling this method.\"\n            raise RuntimeError(msg)\n","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/reflex-dev/reflex/blob/45b8ed5ab735f8a56bbb09a42384f030eb0208e7/packages/reflex-base/src/reflex_base/context/base.py#L46-L82","documentation":"Raised when entering a Context object that is already active in the current execution context. Reflex contexts use a contextvar token stored per-instance (_attached_context_token) to detect double entry; entering twice would corrupt restore semantics, so it raises RuntimeError immediately.","triggerScenarios":"Calling ctx.__enter__() (e.g. `with ctx:`) or `async with ctx:` on a Context instance that is already inside an active with-block, or re-entering the same context object in a nested block within the same task.","commonSituations":"Nesting `with ctx:` blocks accidentally, sharing a module-level Context instance across requests/tasks, or wrapping already-entered context in a helper that also enters it.","solutions":["Ensure each `with ctx:` / `async with ctx:` block is exited before re-entering the same instance","Create a fresh Context instance per scope instead of reusing a shared one","Audit helper functions that enter the context and make sure callers don't also enter it"],"exampleFix":"# before\nctx = rx.context(...)  # shared instance\nwith ctx:\n    ...\nwith ctx:  # RuntimeError: already attached\n    ...\n# after\nwith make_context() as ctx1:\n    ...\nwith make_context() as ctx2:\n    ...\n","handlingStrategy":"type-guard","validationCode":"if ctx._attached_context_token.get(ctx) is not None:\n    raise RuntimeError(\"context already entered — reuse blocked\")","typeGuard":"def is_context_attached(ctx) -> bool:\n    return ctx._attached_context_token.get(ctx) is not None","tryCatchPattern":"null","preventionTips":["Always use `with`/`async with` so exit is guaranteed","Never share one Context instance across concurrent tasks — construct per task"],"tags":["context-manager","runtime","state","async"],"backgroundTag":"context-manager-double-entry","analyzedSha":"45b8ed5ab735f8a56bbb09a42384f030eb0208e7","analyzedAt":"2026-08-28T19:25:27.644Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}