{"record":{"id":"b6a53a9e33d50b62","repo":"apache/flink","slug":"stream-closed","errorCode":null,"errorMessage":"Stream closed.","messagePattern":"Stream closed\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/core/fs/RefCountedBufferingFileStream.java","lineNumber":141,"sourceCode":"        if (!closed) {\n            currentTmpFile.closeStream();\n            closed = true;\n        }\n    }\n\n    @Override\n    public void retain() {\n        currentTmpFile.retain();\n    }\n\n    @Override\n    public boolean release() {\n        return currentTmpFile.release();\n    }\n\n    private void requireOpen() throws IOException {\n        if (closed) {\n            throw new IOException(\"Stream closed.\");\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"Reference Counted File with {\"\n                + \"path=\\'\"\n                + currentTmpFile.getFile().toPath().toAbsolutePath()\n                + \"\\'\"\n                + \", size=\"\n                + getPos()\n                + \", reference counter=\"\n                + currentTmpFile.getReferenceCounter()\n                + \", closed=\"\n                + closed\n                + '}';\n    }\n","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/core/fs/RefCountedBufferingFileStream.java#L123-L159","documentation":"Thrown by RefCountedBufferingFileStream.requireOpen() when any operation (write/flush/getPos) is attempted on a stream whose `closed` flag is true. It is the standard 'use after close' guard for this buffering temp file stream.","triggerScenarios":"Calling write(), flush(), or getPos() on a RefCountedBufferingFileStream after close() has been invoked; double-close paired with a subsequent operation; an exception in one branch leaving the stream closed while another code path keeps writing.","commonSituations":"Sink writer cleanup paths; concurrent close+write during task failure/cancellation; error-handling code that closes on failure but a finally block still attempts to flush.","solutions":["Track ownership: ensure only one code path closes the stream, and no writes follow it.","Reset the reference to null after close and null-check before use.","Use try-with-resources or a lifecycle wrapper that guarantees write/close ordering.","In failure handlers, set a flag and skip subsequent write/flush operations."],"exampleFix":"// before\nstream.write(buffer);\nstream.close();\nstream.flush(); // throws\n\n// after\nstream.write(buffer);\nstream.close();\n// no further operations; or guard:\nif (!stream.isClosed()) { stream.flush(); }","handlingStrategy":"validation","validationCode":"void safeFlush(RefCountedBufferingFileStream s) throws IOException {\n    if (s.isClosed()) return; // or throw IllegalStateException\n    s.flush();\n}","typeGuard":null,"tryCatchPattern":"try {\n    stream.flush();\n} catch (IOException e) {\n    if (\"Stream closed.\".equals(e.getMessage())) { /* already closed, ignore */ return; }\n    throw e;\n}","preventionTips":["Establish single ownership of stream close.","Set the reference to null after close and null-check before use.","Order cleanup so writes always precede close."],"tags":["filesystem","stream","resource-lifecycle","use-after-close"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}