redis/redis-py · error · ResponseError
Wrong number of response items from pipeline execution
Error message
Wrong number of response items from pipeline execution
What it means
Raised in _execute_transaction after EXEC: the number of items in the EXEC response does not equal the number of queued commands. This indicates a protocol-level desynchronization — the client and server disagree on how many replies are outstanding — so the connection is forcibly disconnected and a ResponseError is raised.
Solutions
- Use a dedicated connection for pubsub/push notifications, separate from the pipeline connection.
- Update to the latest redis-py (RESP3 push handling is improved across releases).
- Reduce the transaction to the minimum command set to isolate which command corrupts the reply count.
Example fix
// before
client = redis.asyncio.Redis(protocol=3) # pubsub + tx on one conn
async with client.pipeline(transaction=True) as pipe:
...
// after
client = redis.asyncio.Redis(protocol=3)
pubsub_client = redis.asyncio.Redis(protocol=3) # separate conn for pubsub
async with client.pipeline(transaction=True) as pipe:
... Defensive patterns
Strategy: try-catch
Validate before calling
# Prevent by separating push-capable uses (pubsub, RESP3 pushes) # from MULTI/EXEC onto different connections. client_tx = redis.asyncio.Redis(protocol=3) client_pubsub = redis.asyncio.Redis(protocol=3)
Try / catch
from redis.exceptions import ResponseError
try:
await pipe.execute()
except ResponseError as e:
if 'Wrong number of response items' in str(e):
# connection was force-disconnected; recreate pipeline and retry once
... Prevention
- Never share one connection between pubsub/push and a transaction.
- Keep transactions short and avoid commands that emit out-of-band pushes.
When it happens
Trigger: A bug or race that drops a queued command from the stack mid-flight, a RESP3 push message being consumed as a command reply, or a server-side issue returning a short/long array. Disconnecting is intentional to reset the socket.
Common situations: Using modules/commands that emit out-of-band pushes interleaved with a MULTI/EXEC on the same connection; mixing pubsub and transactions on one connection; corrupted state after a partial network failure.
Related errors
- Unexpected response length for cluster pipeline EXEC…
- Wrong number of response items from pipeline execution
- A occurred while watching one or more keys
- A occurred while watching one or more keys
- All keys involved in a cluster transaction must map to the…
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/13ac6c5b43fd0daf.
Report an issue: GitHub.
Appendix: source
Thrown at redis/asyncio/client.py:2082
except ExecAbortError as err:
if errors:
raise errors[0][1] from err
raise
# EXEC clears any watched keys
self.watching = False
if response is None:
raise WatchError("Watched variable changed.") from None
# put any parse errors into the response
for i, e in errors:
response.insert(i, e)
if len(response) != len(commands):
if self.connection:
await self.connection.disconnect()
raise ResponseError(
"Wrong number of response items from pipeline execution"
) from None
# find any errors in the response and raise if necessary
if raise_on_error:
self.raise_first_error(commands, response)
# We have to run response callbacks manually
data = []
for r, cmd in zip(response, commands):
if not isinstance(r, Exception):
args, options = cmd
command_name = args[0]
# Remove keys entry, it needs only for cache.
options.pop("keys", None)
if command_name in self.response_callbacks:View on GitHub (pinned to 6a6b581b48)