{"record":{"id":"7d629dc9cd0cbda2","repo":"apache/druid","slug":"valuetype-s-is-already-set-cannot-change-to-s","errorCode":null,"errorMessage":"valueType[%s] is already set, cannot change to[%s]","messagePattern":"valueType\\[(.+?)\\] is already set, cannot change to\\[(.+?)\\]","errorType":"exception","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/column/ColumnDescriptor.java","lineNumber":148,"sourceCode":"    for (ColumnPartSerde part : parts) {\n      part.getDeserializer().read(buffer, builder, columnConfig, parent);\n    }\n    return builder.build();\n  }\n\n  public static class Builder\n  {\n    @Nullable\n    private ValueType valueType = null;\n    @Nullable\n    private Boolean hasMultipleValues = null;\n\n    private final List<ColumnPartSerde> parts = new ArrayList<>();\n\n    public Builder setValueType(ValueType valueType)\n    {\n      if (this.valueType != null && this.valueType != valueType) {\n        throw new IAE(\"valueType[%s] is already set, cannot change to[%s]\", this.valueType, valueType);\n      }\n      this.valueType = valueType;\n      return this;\n    }\n\n    public Builder setHasMultipleValues(boolean hasMultipleValues)\n    {\n      if (this.hasMultipleValues != null && this.hasMultipleValues != hasMultipleValues) {\n        throw new IAE(\n            \"hasMultipleValues[%s] is already set, cannot change to[%s]\", this.hasMultipleValues, hasMultipleValues\n        );\n      }\n      this.hasMultipleValues = hasMultipleValues;\n      return this;\n    }\n\n    public Builder addSerde(ColumnPartSerde serde)\n    {","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/column/ColumnDescriptor.java#L130-L166","documentation":"ColumnDescriptor.Builder guards against contradictory metadata while a segment column is serialized: once a valueType is set, calling setValueType with a different ValueType fails. This catches indexers disagreeing on a column's type (e.g. one part says STRING, another LONG).","triggerScenarios":"Building a ColumnDescriptor (e.g. in IndexMerger/index generation paths like makeColumnDescriptor or makeMetricsColumns) where the value type is set twice with differing ValueTypes.","commonSituations":"Merging segments whose identical column has different ValueTypes; custom column serializers or extensions that set the type in two places; corrupted/merged schema metadata across segment versions.","solutions":["Ensure all writers/mergers agree on the column's ValueType before building the descriptor (check input segment schemas)","Remove the redundant setValueType call that conflicts with an earlier one","Re-index/re-ingest segments that have inconsistent column types"],"exampleFix":"// before\nbuilder.setValueType(ValueType.STRING);\n// ... other code ...\nbuilder.setValueType(ValueType.LONG); // IAE\n// after\nbuilder.setValueType(ValueType.LONG); // set once, consistently","handlingStrategy":"validation","validationCode":"// Before building the descriptor, assert all inputs agree:\nassert inputs.stream().map(s -> s.getValueType(col)).distinct().count() == 1;","typeGuard":null,"tryCatchPattern":"try { builder.setValueType(t); } catch (IAE e) { throw new IllegalStateException(\"inconsistent column type across inputs\", e); }","preventionTips":["Verify input segment schemas match before merge","Set valueType exactly once per descriptor build","Run segment-metadata drift checks across the datasource"],"tags":["druid","segment","schema-conflict"],"backgroundTag":"conflicting-config-options","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"}