redis/jedis · error · IllegalStateException
DISCARD without MULTI
Error message
DISCARD without MULTI
What it means
Thrown by Transaction.discard() when called outside an active MULTI block: inMulti is false because MULTI was never sent or the transaction was already executed/reset, so there is nothing for the server to DISCARD. It is a client-side state guard that avoids sending an invalid command sequence.
Solutions
- Only call discard() while the transaction is open (after multi(), before exec()).
- Guard cleanup code with a flag or check before discarding.
- If the block was already exec'd, discard is unnecessary — skip it.
- Create a new Transaction if a fresh block is needed.
Example fix
// before
Transaction t = jedis.transaction(false);
t.discard(); // throws: never in MULTI
// after
Transaction t = jedis.transaction(false);
t.multi();
t.set("k", "v");
t.discard(); Defensive patterns
Strategy: validation
Validate before calling
boolean blockOpen = startedMulti && !executed; if (blockOpen) tx.discard();
Try / catch
try {
tx.discard();
} catch (IllegalStateException e) {
// block already closed; safe to ignore
} Prevention
- Only discard an open MULTI block
- Use a flag to track transaction state in cleanup paths
- Avoid unconditional discard in finally blocks
When it happens
Trigger: Calling discard() on a Transaction created with doMulti=true before any commands (MULTI already implicit? no — discard before multi in manual mode), calling discard() twice, or calling discard() after exec() already closed the block.
Common situations: Cleanup/finally blocks that unconditionally call discard(); error-handling paths where the transaction never entered MULTI; double abort attempts.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- EXEC without MULTI
- DISCARD without MULTI
- DISCARD command failed. Received response
- Please close pipeline or multi block before calling this…
- It is not allowed to create Transaction from this
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/8d518799dccda74c.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/Transaction.java:224
formatted.add(e);
}
}
return formatted;
} catch (JedisConnectionException jce) {
broken = true;
throw jce;
} finally {
inMulti = false;
inWatch = false;
pipelinedResponses.clear();
onAfterExec();
}
}
@Override
public String discard() {
if (!inMulti) {
throw new IllegalStateException("DISCARD without MULTI");
}
try {
// ignore QUEUED (or ERROR)
// processPipelinedResponses(pipelinedResponses.size());
connection.getMany(1 + pipelinedResponses.size());
connection.sendCommand(DISCARD);
return connection.getStatusCodeReply();
} catch (JedisConnectionException jce) {
broken = true;
throw jce;
} finally {
inMulti = false;
inWatch = false;
pipelinedResponses.clear();
onAfterDiscard();View on GitHub (pinned to 6dac31d4c2)