redis/redis-py · error · RedisClusterException
method discard() is not supported outside of transactional…
Error message
method discard() is not supported outside of transactional context
What it means
Raised by AbstractStrategy.discard() in redis/cluster.py:4552. DISCARD aborts a MULTI transaction, but a non-transactional cluster pipeline never entered MULTI, so there is nothing to discard. The cluster pipeline exposes discard only on its transactional strategy path.
Solutions
- Only call discard() inside a transactional pipeline (rc.pipeline(transaction=True)) after MULTI was implicitly started.
- For a non-transactional pipeline, call pipe.reset() to clear the command queue instead of discard().
- Guard the discard call so it only runs when a transaction is actually in progress.
Example fix
// before
pipe = rc.pipeline()
try:
pipe.set('k', 'v')
pipe.discard()
// after
pipe = rc.pipeline()
pipe.reset() # clear non-transactional queue Defensive patterns
Strategy: validation
Validate before calling
if getattr(pipe, 'transaction', False):
pipe.discard()
else:
pipe.reset() Type guard
def is_transactional_pipe(pipe) -> bool:
return bool(getattr(pipe, 'transaction', False)) Try / catch
from redis.exceptions import RedisClusterException
try:
pipe.discard()
except RedisClusterException:
pipe.reset() Prevention
- Use reset() on non-transactional pipelines.
- Guard cleanup calls behind a transaction check.
When it happens
Trigger: Calling pipe.discard() on a non-transactional ClusterPipeline (rc.pipeline(transaction=False) or default), or calling discard before multi/transaction was started.
Common situations: Standalone pipeline code ported to cluster; exception handlers that unconditionally call pipe.discard() to clean up.
Related errors
- Cannot issue a WATCH after a MULTI
- method multi() is not supported outside of transactional…
- method unwatch() is not supported outside of transactional…
- method watch() is not supported outside of transactional…
- 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/b6abe73090214557.
Report an issue: GitHub.
Appendix: source
Thrown at redis/cluster.py:4552
elif request_policy == RequestPolicy.MULTI_SHARD:
nodes = policy_callback(*args, **kwargs)
elif request_policy == RequestPolicy.DEFAULT_KEYLESS:
nodes = policy_callback(args[0])
else:
nodes = policy_callback()
if args[0].lower() == "ft.aggregate":
self._aggregate_nodes = nodes
return nodes
def multi(self):
raise RedisClusterException(
"method multi() is not supported outside of transactional context"
)
def discard(self):
raise RedisClusterException(
"method discard() is not supported outside of transactional context"
)
def watch(self, *names):
raise RedisClusterException(
"method watch() is not supported outside of transactional context"
)
def unwatch(self, *names):
raise RedisClusterException(
"method unwatch() is not supported outside of transactional context"
)
def delete(self, *names):
if len(names) != 1:
raise RedisClusterException(
"deleting multiple keys is not implemented in pipeline command"
)View on GitHub (pinned to 6a6b581b48)