redis/redis-py · error · DataError
MIGRATE requires at least one key
Error message
MIGRATE requires at least one key
What it means
Raised by migrate() (redis/commands/core.py:1836) when the keys argument normalizes (via list_or_args) to an empty list. MIGRATE with no keys is invalid at the protocol level, so the library rejects it before sending. This is a redis.exceptions.DataError raised client-side.
Solutions
- Guard the call: if keys: r.migrate(host, port, keys, dest_db, timeout)
- Pass at least one key as a list: r.migrate(host, port, ["k1"], dest_db, timeout)
- list_or_args also accepts a single key string, so r.migrate(host, port, "k1", dest_db, timeout) works
Example fix
# before
r.migrate(host, port, selected_keys, dest_db, timeout)
# after
if selected_keys:
r.migrate(host, port, selected_keys, dest_db, timeout) Defensive patterns
Strategy: validation
Validate before calling
keys = list_or_args(keys, []) if not isinstance(keys, list) else keys
if not keys:
# nothing to migrate; skip
return
r.migrate(host, port, keys, destination_db, timeout) Try / catch
from redis.exceptions import DataError
try:
r.migrate(host, port, keys, dest_db, timeout)
except DataError as e:
if "requires at least one key" in str(e):
pass # empty key set is a no-op
else:
raise Prevention
- Guard migrate() with 'if keys:' before calling.
- Filter key sets before migration and treat empty as a skip.
- Remember list_or_args accepts a single string OR a list.
When it happens
Trigger: Calling r.migrate(host, port, [], dest_db, timeout) with an empty list, or r.migrate(host, port, "", dest_db, timeout), or passing a variable that evaluates to no keys after list_or_args expansion.
Common situations: Migrating a dynamic key set that happens to be empty for a given shard/partition; filtering keys down to none before migrating.
Related errors
- bit must be 0 or 1
- Both start and end must be specified
- ``byfloat`` and ``byint`` are mutually exclusive.
- client_id must be a list
- CLIENT KILL ... ... must specify at least one filter
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/ff7ba4cefb914d0c.
Report an issue: GitHub.
Appendix: source
Thrown at redis/commands/core.py:1836
The ``timeout``, specified in milliseconds, indicates the maximum
time the connection between the two servers can be idle before the
command is interrupted.
If ``copy`` is True, the specified ``keys`` are NOT deleted from
the source server.
If ``replace`` is True, this operation will overwrite the keys
on the destination server if they exist.
If ``auth`` is specified, authenticate to the destination server with
the password provided.
For more information, see https://redis.io/commands/migrate
"""
keys = list_or_args(keys, [])
if not keys:
raise DataError("MIGRATE requires at least one key")
pieces = []
if copy:
pieces.append(b"COPY")
if replace:
pieces.append(b"REPLACE")
if auth:
pieces.append(b"AUTH")
pieces.append(auth)
pieces.append(b"KEYS")
pieces.extend(keys)
return self.execute_command(
"MIGRATE", host, port, "", destination_db, timeout, *pieces, **kwargs
)
@overload
def object(self: SyncClientProtocol, infotype: str, key: KeyT, **kwargs) -> Any: ...
@overloadView on GitHub (pinned to 6a6b581b48)