{"record":{"id":"739e2df053e402f0","repo":"apache/druid","slug":"written-out-already","errorCode":null,"errorMessage":"written out already","messagePattern":"written out already","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/data/BlockLayoutColumnarDoublesSerializer.java","lineNumber":93,"sourceCode":"  }\n\n  @Override\n  public void open() throws IOException\n  {\n    flattener.open();\n  }\n\n  @Override\n  public int size()\n  {\n    return numInserted;\n  }\n\n  @Override\n  public void add(double value) throws IOException\n  {\n    if (endBuffer == null) {\n      throw new IllegalStateException(\"written out already\");\n    }\n    if (!endBuffer.hasRemaining()) {\n      endBuffer.rewind();\n      flattener.write(endBuffer);\n      endBuffer.clear();\n    }\n\n    endBuffer.putDouble(value);\n    ++numInserted;\n    if (numInserted < 0) {\n      throw new ColumnCapacityExceededException(columnName);\n    }\n  }\n\n  @Override\n  public long getSerializedSize() throws IOException\n  {\n    writeEndBuffer();","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/data/BlockLayoutColumnarDoublesSerializer.java#L75-L111","documentation":"BlockLayoutColumnarDoublesSerializer.add(double) appends a double to the block-based serializer. Once the serializer is closed (endBuffer nulled out by close/flush), it throws IllegalStateException('written out already') because writing after finalization would corrupt the segment file.","triggerScenarios":"Calling add() after close() (or after the serializer finished writing its last block and was written out), e.g. continuing to feed values after completing a column.","commonSituations":"Ingestion/task code paths that write more rows than declared; exception-handling bugs that retry add after close; reusing a serializer instance for a second column.","solutions":["Ensure no add() calls occur after close()/write-out; finish all adds first","Create a new serializer instance for each column/write session","Check serializer state (endBuffer != null) before adding in defensive code"],"exampleFix":"// before\nserializer.close();\nserializer.add(value);\n// after\nserializer.add(value);\nserializer.close();","handlingStrategy":"try-catch","validationCode":"if (serializer != null && serializer.isOpen()) { serializer.add(value); }","typeGuard":"boolean canAdd(BlockLayoutColumnarDoublesSerializer s) { return s != null && s.isOpen(); } // if state accessor exists; otherwise track closed flag locally","tryCatchPattern":"try { serializer.add(value); } catch (IllegalStateException e) { throw new IOException(\"Serializer already closed; row count exceeded declared numRows\", e); }","preventionTips":["Write all values before calling close(); never add after finalization","Track writer lifecycle with explicit open/closed state","Create a fresh serializer per column; do not reuse closed instances"],"tags":["java","invalid-state","serialization","segments"],"backgroundTag":"invalid-state-transition","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}