{"record":{"id":"1f1b08f256e15571","repo":"apache/iceberg","slug":"hashwriter-is-closed","errorCode":null,"errorMessage":"HashWriter is closed.","messagePattern":"HashWriter is closed\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/util/HashWriter.java","lineNumber":75,"sourceCode":"  public void close() throws IOException {\n    isClosed = true;\n  }\n\n  /**\n   * Calculates the final hash value. The underlying digest will be reset thus subsequent getHash()\n   * calls are not permitted.\n   *\n   * @return bytes of final hash value\n   */\n  public byte[] getHash() {\n    ensureNotClosed();\n    isClosed = true;\n    return digest.digest();\n  }\n\n  private void ensureNotClosed() {\n    if (isClosed) {\n      throw new IllegalStateException(\"HashWriter is closed.\");\n    }\n  }\n}\n","sourceCodeStart":57,"sourceCodeEnd":79,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/util/HashWriter.java#L57-L79","documentation":"HashWriter.ensureNotClosed() throws IllegalStateException once the writer has finished hashing (after getHash() closes it). A HashWriter is single-use: after digest retrieval it cannot accept writes or produce another hash.","triggerScenarios":"Calling write(byte[], int, int) or getHash() after a previous getHash() call set isClosed=true.","commonSituations":"Reusing a cached HashWriter instance across rows or files; calling getHash() twice to read the digest incrementally; resuming an aborted write after finalization.","solutions":["Create a new HashWriter for each hash computation","Read the digest once and store the result instead of calling getHash() repeatedly","Refactor code to accumulate all writes before finalizing"],"exampleFix":"// before\nhashWriter.write(data);\nbyte[] h1 = hashWriter.getHash();\nbyte[] h2 = hashWriter.getHash(); // throws\n// after\nhashWriter.write(data);\nbyte[] hash = hashWriter.getHash();\nbyte[] h1 = hash, h2 = hash;","handlingStrategy":"try-catch","validationCode":"if (hashWriterClosed) throw new IllegalStateException(\"create a new HashWriter\");","typeGuard":null,"tryCatchPattern":"try { byte[] h = hashWriter.getHash(); } catch (IllegalStateException e) { hashWriter = new HashWriter(algorithm); /* redo */ }","preventionTips":["Treat HashWriter as single-use: one final getHash() call","Cache the digest result instead of re-reading","Create a fresh HashWriter per hash computation"],"tags":["hashing","state","single-use"],"backgroundTag":"invalid-state-transition","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}