{"id":"8031004339dcb6f6","repo":"redis/redis-py","slug":"cannot-disable-maintenance-notifications-after-ena","errorCode":null,"errorMessage":"Cannot disable maintenance notifications after enabling them","messagePattern":"Cannot disable maintenance notifications after enabling them","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/asyncio/connection.py","lineNumber":2048,"sourceCode":"    async def update_maint_notifications_config(\n        self,\n        maint_notifications_config: MaintNotificationsConfig,\n        oss_cluster_maint_notifications_handler: (\n            AsyncOSSMaintNotificationsHandler | None\n        ) = None,\n    ) -> None:\n        \"\"\"\n        Updates the maintenance notifications configuration.\n        This method should be called only if the pool was created\n        without enabling the maintenance notifications and\n        in a later point in time maintenance notifications\n        are requested to be enabled.\n        \"\"\"\n        if (\n            self.maint_notifications_enabled()\n            and not maint_notifications_config.enabled\n        ):\n            raise ValueError(\n                \"Cannot disable maintenance notifications after enabling them\"\n            )\n\n        if oss_cluster_maint_notifications_handler:\n            self._oss_cluster_maint_notifications_handler = (\n                oss_cluster_maint_notifications_handler\n            )\n            # OSS cluster mode and pool-handler mode are mutually exclusive\n            # (see __init__). A pool created with the default RESP3 \"auto\"\n            # config wires a pool handler before this method runs; clear it so\n            # new and existing connections are not configured with both handlers.\n            self._maint_notifications_pool_handler = None\n        else:\n            if (\n                maint_notifications_config.enabled\n                and not self._maintenance_notifications_supported()\n            ):\n                if maint_notifications_config.enabled is True:","sourceCodeStart":2030,"sourceCodeEnd":2066,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/asyncio/connection.py#L2030-L2066","documentation":"Raised when update_maint_notifications_config() is called with a config whose 'enabled' flag is False while the pool already has maintenance notifications enabled. Maintenance notifications are designed as a one-way switch: once a pool is configured to receive them, the connections, parser hooks, and handlers are wired in and cannot be torn down by simply flipping the flag back off. To 'disable' you must recreate the pool/client without the maintenance-notifications config.","triggerScenarios":"Calling ConnectionPool.update_maint_notifications_config(MaintNotificationsConfig(enabled=False)) (or Redis/RedisCluster.update_maint_notifications_config with enabled=False) on a pool where maint_notifications_enabled() already returns True. Also hit indirectly by clients that re-apply a config object with enabled defaulted to False during a reconfiguration step.","commonSituations":"Building a control plane that toggles maintenance notifications on/off at runtime; copying a config template whose 'enabled' defaults to False and passing it to the update API; misreading the docstring which only describes enabling, not disabling.","solutions":["Recreate the Redis client / connection pool from scratch instead of trying to disable notifications on an existing one: disconnect() then construct a new Redis(...) without the maintenance-notifications config.","If you must call update_maint_notifications_config, ensure the MaintNotificationsConfig you pass has enabled=True (this path is enable-only).","Track your own 'enabled' state and short-circuit before calling the API when you intend to turn it off."],"exampleFix":"// before\nawait pool.update_maint_notifications_config(\n    MaintNotificationsConfig(enabled=False)\n)\n// after\nawait pool.disconnect()\nredis = Redis.from_url(url)  # fresh pool, no maint-notifications config","handlingStrategy":"validation","validationCode":"async def safe_update_maint_config(pool, config):\n    if not config.enabled and pool.maint_notifications_enabled():\n        # one-way switch: do not call update with enabled=False\n        return False\n    await pool.update_maint_notifications_config(config)\n    return True","typeGuard":"def is_disable_attempt(pool, config) -> bool:\n    return pool.maint_notifications_enabled() and not getattr(config, 'enabled', True)","tryCatchPattern":"try:\n    await pool.update_maint_notifications_config(config)\nexcept ValueError as e:\n    if 'Cannot disable' in str(e):\n        # recreate the pool instead\n        ...","preventionTips":["Treat maintenance notifications as enable-only on a given pool instance.","Recreate the client/pool to 'disable' rather than passing enabled=False.","Track your own enabled flag and skip the update call when disabling."],"tags":["maintenance-notifications","configuration","asyncio","pool"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}