{"record":{"id":"c64bd9118fc86503","repo":"redis/jedis","slug":"please-close-pipeline-or-multi-block-before-callin","errorCode":null,"errorMessage":"Please close pipeline or multi block before calling this method.","messagePattern":"Please close pipeline or multi block before calling this method\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/Response.java","lineNumber":34,"sourceCode":"  private Response<?> dependency = null;\n\n  public Response(Builder<T> b) {\n    this.builder = b;\n  }\n\n  public void set(Object data) {\n    this.data = data;\n    set = true;\n  }\n\n  @Override\n  public T get() {\n    // if response has dependency response and dependency is not built, build it first and no more!!\n    if (dependency != null && dependency.set && !dependency.built) {\n      dependency.build();\n    }\n    if (!set) {\n      throw new IllegalStateException(\n          \"Please close pipeline or multi block before calling this method.\");\n    }\n    if (!built) {\n      build();\n    }\n    if (exception != null) {\n      throw exception;\n    }\n    return response;\n  }\n\n  public void setDependency(Response<?> dependency) {\n    this.dependency = dependency;\n  }\n\n  private void build() {\n    // check build state to prevent recursion\n    if (building) {","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/Response.java#L16-L52","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nPipeline p = jedis.pipelined();\nResponse<String> r = p.get(\"key\");\nString v = r.get(); // throws\np.sync();\n// after\nPipeline p = jedis.pipelined();\nResponse<String> r = p.get(\"key\");\np.sync();\nString v = r.get();","handlingStrategy":"try-catch","validationCode":"// before reading responses\nif (!pipeline.isClosed()) { /* call sync()/exec() first */ }","typeGuard":null,"tryCatchPattern":"try { pipeline.sync(); } catch (JedisException e) { /* handle */ }\nT val = response.get();","preventionTips":["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"],"tags":["pipeline","transaction","jedis","illegal-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"6dac31d4c224fb3257c216f3985340c6f500cdcb","analyzedAt":"2026-09-08T04:55:01.204Z","contentChangedAt":"2026-09-08T04:55:01.204Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}