{"record":{"id":"b2bd76ebaf987630","repo":"apache/druid","slug":"written-out-already-b2bd76","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/IntermediateColumnarLongsSerializer.java","lineNumber":97,"sourceCode":"\n  @Override\n  public void open()\n  {\n    tempOut = new LongArrayList();\n  }\n\n  @Override\n  public int size()\n  {\n    return numInserted;\n  }\n\n  @Override\n  public void add(long value)\n  {\n    //noinspection VariableNotUsedInsideIf\n    if (delegate != null) {\n      throw new IllegalStateException(\"written out already\");\n    }\n    tempOut.add(value);\n    ++numInserted;\n    if (numInserted < 0) {\n      throw new ColumnCapacityExceededException(columnName);\n    }\n    if (uniqueValues.size() <= CompressionFactory.MAX_TABLE_SIZE && !uniqueValues.containsKey(value)) {\n      uniqueValues.put(value, uniqueValues.size());\n      valuesAddedInOrder.add(value);\n    }\n    if (value > maxVal) {\n      maxVal = value;\n    }\n    if (value < minVal) {\n      minVal = value;\n    }\n  }\n","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/data/IntermediateColumnarLongsSerializer.java#L79-L115","documentation":"IntermediateColumnarLongsSerializer buffers longs into a temp output; once the column has been serialized (written out), the delegate is set and add() is permanently disabled. Calling add() after that transition throws this IllegalStateException because new values can no longer be inserted into the finished column.","triggerScenarios":"Calling add(long) after close()/writeTo() has completed serialization of the column; reusing a serializer across columns without constructing a new instance.","commonSituations":"Custom segment generation code that keeps appending after finishing a column; aggregation logic that writes more rows than declared to the ingester; reusing a serializer object for multiple input files.","solutions":["Create a new IntermediateColumnarLongsSerializer for each column instead of reusing a finished one","Ensure all add() calls happen before close()/serialization completes","Audit aggregation code paths for values arriving after the column was flushed"],"exampleFix":"// before\nserializer.close();\nserializer.add(42L); // throws\n// after\nserializer.close();\nIntermediateColumnarLongsSerializer next = serializerFactory.makeSerializer(...);\nnext.add(42L);","handlingStrategy":"validation","validationCode":"if (serializer.isDone()) { serializer = factory.makeSerializer(...); }","typeGuard":null,"tryCatchPattern":"try { serializer.add(v); } catch (IllegalStateException e) { throw new IOException(\"column already finalized; create a new serializer\", e); }","preventionTips":["Call add() strictly before close()/writeTo()","Use one serializer per column; never reuse after finalization","Track flush state in ingestion code paths"],"tags":["druid","segment","serialization"],"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-17T15:17:12.973Z"}