{"record":{"id":"5e9c4631067a6549","repo":"apache/druid","slug":"hasmultiplevalues-s-is-already-set-cannot-chang","errorCode":null,"errorMessage":"hasMultipleValues[%s] is already set, cannot change to[%s]","messagePattern":"hasMultipleValues\\[(.+?)\\] 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":157,"sourceCode":"    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    {\n      parts.add(serde);\n      return this;\n    }\n\n    public ColumnDescriptor build()\n    {\n      Preconditions.checkNotNull(valueType, \"must specify a valueType\");\n      return new ColumnDescriptor(valueType, hasMultipleValues == null ? false : hasMultipleValues, parts);\n    }","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/column/ColumnDescriptor.java#L139-L175","documentation":"Companion guard to the valueType check: ColumnDescriptor.Builder.setHasMultipleValues rejects changing a previously set multi-value flag to a different value. It ensures a column's multi-valuedness is consistent across all parts written into the descriptor.","triggerScenarios":"Building a column descriptor where setHasMultipleValues(true) then setHasMultipleValues(false) (or vice versa) is called, e.g. metrics/indexer code paths disagreeing on multi-valuedness.","commonSituations":"Merging segments where the same column is single-valued in one and multi-valued in another; custom aggregators or extensions setting the flag twice; arrays introduced to a previously scalar column.","solutions":["Make input segments consistent: the column must be uniformly single- or multi-valued across merged segments","Fix the code path that sets the flag twice with different values","Re-ingest data with normalized (single- or array-typed) values for the column"],"exampleFix":"// before\nbuilder.setHasMultipleValues(true);\nbuilder.setHasMultipleValues(false); // IAE\n// after\nbuilder.setHasMultipleValues(hasMultipleValues); // computed once from the column","handlingStrategy":"validation","validationCode":"Set<Boolean> flags = inputs.stream().map(s -> s.hasMultipleValues(col)).collect(Collectors.toSet());\nif (flags.size() > 1) throw new IllegalStateException(\"mixed multi-valuedness\");","typeGuard":null,"tryCatchPattern":"try { builder.setHasMultipleValues(mv); } catch (IAE e) { /* reconcile flag from inputs and rebuild */ }","preventionTips":["Normalize single/multi-valuedness at ingestion before merging","Set the flag once, derived from the actual column","Include multi-valuedness in pre-merge schema validation"],"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"}