redis/jedis · error · IllegalStateException
Please close pipeline or multi block before calling this…
Error message
Please close pipeline or multi block before calling this method.
What it means
Response<T> buffers a single command's result inside a Pipeline or MULTI/EXEC transaction block. Calling get() before the block has been closed (exec'd) means the reply has not been read from the server, so Jedis throws IllegalStateException. The response is only 'set' once the pipeline/transaction is synchronised.
Solutions
- Call pipeline.sync() (discard replies) or pipeline.syncAndReturnAll() before reading any Response.get().
- For transactions, call transaction.exec() before reading responses.
- Restructure code so all Response.get() calls happen after the block is closed.
- If you need per-command results immediately, drop the pipeline and issue regular synchronous commands instead.
Example fix
// before
Pipeline p = jedis.pipelined();
Response<String> r = p.get("key");
String v = r.get(); // throws
p.sync();
// after
Pipeline p = jedis.pipelined();
Response<String> r = p.get("key");
p.sync();
String v = r.get(); Defensive patterns
Strategy: try-catch
Validate before calling
// before reading responses
if (!pipeline.isClosed()) { /* call sync()/exec() first */ } Try / catch
try { pipeline.sync(); } catch (JedisException e) { /* handle */ }
T val = response.get(); Prevention
- Never call Response.get() before sync()/exec()
- Collect all Response references, then sync, then read
- Keep pipeline blocks small and well-scoped
- Avoid mixing direct reads inside pipeline blocks
When it happens
Trigger: Calling response.get() on an object returned by Pipeline.appendCommand/Multi transactions before calling pipeline.sync()/sync() or transaction.exec(). E.g. 'Response<String> r = pipeline.get("k"); String v = r.get();' without sync() first.
Common situations: Mixing pipelined calls with immediate reads; forgetting that pipelining is asynchronous; copy-pasting non-pipelined code into a pipeline block; exceptions swallowed earlier so sync() never ran.
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
- Cannot use Jedis when in Multi. Please use Transaction or…
- Cannot use Jedis when in Pipeline. Please use Pipeline or…
- DISCARD without MULTI
- It is not allowed to create Pipeline from this
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/c64bd9118fc86503.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/Response.java:34
private Response<?> dependency = null;
public Response(Builder<T> b) {
this.builder = b;
}
public void set(Object data) {
this.data = data;
set = true;
}
@Override
public T get() {
// if response has dependency response and dependency is not built, build it first and no more!!
if (dependency != null && dependency.set && !dependency.built) {
dependency.build();
}
if (!set) {
throw new IllegalStateException(
"Please close pipeline or multi block before calling this method.");
}
if (!built) {
build();
}
if (exception != null) {
throw exception;
}
return response;
}
public void setDependency(Response<?> dependency) {
this.dependency = dependency;
}
private void build() {
// check build state to prevent recursion
if (building) {View on GitHub (pinned to 6dac31d4c2)