redis/redis-py · error · ValueError

Given database is not a member of database list

Error message

Given database is not a member of database list

What it means

Raised by `MultiDBClient.set_active_database()` (redis/asyncio/multidb/client.py:164) when the passed `AsyncDatabase` object is not present in the client's internal `_databases` weighted list. Membership is checked by equality (`existing_db == database`), so a database constructed independently or belonging to another MultiDBClient instance will not match.

Source

Thrown at redis/asyncio/multidb/client.py:164

    def get_databases(self) -> Databases:
        """
        Returns a sorted (by weight) list of all databases.
        """
        return self._databases

    async def set_active_database(self, database: AsyncDatabase) -> None:
        """
        Promote one of the existing databases to become an active.
        """
        exists = None

        for existing_db, _ in self._databases:
            if existing_db == database:
                exists = True
                break

        if not exists:
            raise ValueError("Given database is not a member of database list")

        await self._check_db_health(database)

        if database.circuit.state == CBState.CLOSED:
            highest_weighted_db, _ = self._databases.get_top_n(1)[0]
            await self.command_executor.set_active_database(
                database, GeoFailoverReason.MANUAL
            )
            return

        raise NoValidDatabaseException(
            "Cannot set active database, database is unhealthy"
        )

    async def add_database(
        self, config: DatabaseConfig, skip_initial_health_check: bool = True
    ):
        """

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Obtain the database from `client.get_databases()` and pass that exact object: `[db for db, _ in client.get_databases()]`.
  2. If adding a new database, use `await client.add_database(config)` first, then retrieve it from `get_databases()`.
  3. Do not construct `Database(...)` directly to pass into `set_active_database`.

Example fix

# before
db = Database(client=my_client, circuit=cb, weight=1.0)
await client.set_active_database(db)  # ValueError

# after
dbs = [db for db, _ in client.get_databases()]
await client.set_active_database(dbs[0])
Defensive patterns

Strategy: validation

Validate before calling

def database_is_registered(client, database) -> bool:
    return any(db is database for db, _ in client.get_databases())

# assert database_is_registered(client, db) before set_active_database

Type guard

from redis.asyncio.multidb.database import AsyncDatabase

def is_registered_database(client, obj) -> bool:
    return isinstance(obj, AsyncDatabase) and any(db is obj for db, _ in client.get_databases())

Try / catch

try:
    await client.set_active_database(db)
except ValueError as e:
    if 'not a member' in str(e):
        # fetch a valid db from get_databases() and retry
        ...
    raise

Prevention

When it happens

Trigger: Calling `await client.set_active_database(db)` where `db` was not obtained from `client.get_databases()` — e.g. a freshly constructed `Database(...)` object, a database from a different MultiDBClient, or a stale reference after `remove_database()`.

Common situations: Building a Database manually instead of fetching it from the client; passing a database from one MultiDBClient into another; holding a reference to a database that was removed.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/f7d257d0557f87fb.json. Report an issue: GitHub.