{"record":{"id":"57c226244b232dc9","repo":"apache/hadoop","slug":"stream-closed","errorCode":null,"errorMessage":"Stream closed","messagePattern":"Stream closed","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-bos/src/main/java/org/apache/hadoop/fs/bos/BosOutputStream.java","lineNumber":166,"sourceCode":"            \"catch exception when allocating\"\n                + \" BosBlockBuffer: \",\n            throwable);\n      }\n    }\n  }\n\n  /**\n   * Writes a single byte to this output stream.\n   *\n   * @param b the byte to write\n   * @throws IOException if the stream is closed or an I/O\n   *                     error occurs\n   */\n  @Override\n  public synchronized void write(int b)\n      throws IOException {\n    if (this.closed) {\n      throw new IOException(\"Stream closed\");\n    }\n\n    flush();\n    createBlockBufferIfNull();\n\n    this.currBlock.getOutBuffer().write(b);\n    this.bytesWrittenToBlock++;\n    this.filePos++;\n  }\n\n  /**\n   * Writes bytes from the specified buffer to this output\n   * stream.\n   *\n   * @param b   the data buffer\n   * @param off the start offset in the data\n   * @param len the number of bytes to write\n   * @throws IOException if the stream is closed or an I/O","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-bos/src/main/java/org/apache/hadoop/fs/bos/BosOutputStream.java#L148-L184","documentation":"BosOutputStream.write(int) is synchronized and checks the closed flag first; after close() (or the internal abort path) sets it, writing a single byte throws plain IOException('Stream closed') before flush() or buffer allocation run.","triggerScenarios":"Calling write(int) after close(); two threads sharing the output stream where one closes; writing from a callback/lambda that outlives the stream's scope.","commonSituations":"Cleanup code in finally that writes a trailer after an earlier close; framework writers (SequenceFile-style) double-closing wrapped streams; error paths that close early then continue appending.","solutions":["Confine the stream to one owner and one lifecycle: try-with-resources exactly around the writing code","In finally blocks, never write after close — restructure so close() is the last operation, exactly once","Wrap the stream and track a local closed flag if multiple components may close it"],"exampleFix":"// before\nout.close();\nout.write(b); // cleanup writes trailer after close\n\n// after\nwriteTrailer(out);\nout.close(); // close exactly once, last","handlingStrategy":"validation","validationCode":"// wrapper that makes post-close writes explicit\nif (!wrapperClosed) { out.write(b); } else { throw new IllegalStateException(\"writer already finished\"); }","typeGuard":"static boolean isClosedWrite(IOException e) {\n  return \"Stream closed\".equals(e.getMessage());\n}","tryCatchPattern":"catch (IOException e) {\n  if (isClosedWrite(e)) {\n    out = fs.create(path, overwrite); // start a new object; old stream is finished\n  } else { throw e; }\n}","preventionTips":["Close exactly once, in finally, as the last operation","Never write from cleanup paths after close","One owner thread per output stream"],"tags":["bos","output-stream","stream-closed","lifecycle","hadoop"],"backgroundTag":"io-stream-closed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}