{"record":{"id":"16d7683242527051","repo":"redis/redis-py","slug":"either-maint-notifications-pool-handler-or-oss-clu","errorCode":null,"errorMessage":"Either maint_notifications_pool_handler or oss_cluster_maint_notifications_handler must be set","messagePattern":"Either maint_notifications_pool_handler or oss_cluster_maint_notifications_handler must be set","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/connection.py","lineNumber":2699,"sourceCode":"        with self._get_pool_lock():\n            for conn in self._get_free_connections():\n                if oss_cluster_maint_notifications_handler:\n                    # set cluster handler for conn\n                    conn.set_maint_notifications_cluster_handler_for_connection(\n                        oss_cluster_maint_notifications_handler\n                    )\n                    conn.maint_notifications_config = (\n                        oss_cluster_maint_notifications_handler.config\n                    )\n                elif maint_notifications_pool_handler:\n                    conn.set_maint_notifications_pool_handler_for_connection(\n                        maint_notifications_pool_handler\n                    )\n                    conn.maint_notifications_config = (\n                        maint_notifications_pool_handler.config\n                    )\n                else:\n                    raise ValueError(\n                        \"Either maint_notifications_pool_handler or oss_cluster_maint_notifications_handler must be set\"\n                    )\n                conn.disconnect()\n            for conn in self._get_in_use_connections():\n                if oss_cluster_maint_notifications_handler:\n                    # Use set_maint_notifications_cluster_handler_for_connection\n                    # (not _configure_maintenance_notifications) so the parser is\n                    # obtained from the connection itself. _configure_* requires a\n                    # parser argument and would raise here; it would also reset the\n                    # connection's orig_* settings, which is wrong for an in-use\n                    # (active) connection. This mirrors the idle-connection branch\n                    # above and the pool-handler branches.\n                    conn.set_maint_notifications_cluster_handler_for_connection(\n                        oss_cluster_maint_notifications_handler\n                    )\n                    conn.maint_notifications_config = (\n                        oss_cluster_maint_notifications_handler.config\n                    )","sourceCodeStart":2681,"sourceCodeEnd":2717,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/connection.py#L2681-L2717","documentation":"Raised as ValueError inside _update_maint_notifications_configs_for_connections (the loop over _get_free_connections) when maintenance notifications are considered enabled but neither maint_notifications_pool_handler nor oss_cluster_maint_notifications_handler is provided to the method. This is an internal invariant of the pool: the public update_maint_notifications_config always supplies one handler, so reaching this branch implies a programming error inside the library or a subclass that overrides the update helpers incorrectly.","triggerScenarios":"Calling _update_maint_notifications_configs_for_connections directly with both handler arguments None, or a subclass of the pool that overrides maint_notifications_enabled/_update_maint_notifications_configs_for_connections such that the invariant breaks.","commonSituations":"Subclassing the maintenance-notifications pool and breaking the handler contract. Library-internal logic error. Very unlikely from normal client usage.","solutions":["Do not call _update_maint_notifications_configs_for_connections directly; use update_maint_notifications_config, which always supplies a handler.","If you subclass the pool, preserve the invariant that exactly one handler is non-None whenever maintenance notifications are enabled.","Report a bug if this surfaces from unmodified library code."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"# Internal invariant: do not call _update_maint_notifications_configs_for_connections directly.\n# Always ensure a handler is present before updating:\nif pool.maint_notifications_enabled():\n    assert pool._maint_notifications_pool_handler or pool._oss_cluster_maint_notifications_handler\npool.update_maint_notifications_config(cfg)","typeGuard":null,"tryCatchPattern":"try:\n    pool.update_maint_notifications_config(cfg)\nexcept ValueError as e:\n    if 'must be set' in str(e):\n        # internal invariant broken; recreate the pool\n        pool = ConnectionPool(maint_notifications_config=cfg)\n    else:\n        raise","preventionTips":["Use the public update API rather than internal helpers.","If subclassing, preserve the one-handler invariant.","Report library bugs that surface this from unmodified code."],"tags":["maintenance-notifications","internal","invariant"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}