{"record":{"id":"85514f6893f0be04","repo":"apache/druid","slug":"duplicate-virtualcolumn-name-s","errorCode":null,"errorMessage":"Duplicate virtualColumn name[%s]","messagePattern":"Duplicate virtualColumn name\\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/VirtualColumns.java","lineNumber":120,"sourceCode":"  {\n    return create(Arrays.asList(virtualColumns));\n  }\n\n  public static VirtualColumns fromIterable(Iterable<VirtualColumn> virtualColumns)\n  {\n    Map<String, VirtualColumn> withDotSupport = new HashMap<>();\n    Map<String, VirtualColumn> withoutDotSupport = new HashMap<>();\n    for (VirtualColumn vc : virtualColumns) {\n      if (Strings.isNullOrEmpty(vc.getOutputName())) {\n        throw new IAE(\"Empty or null virtualColumn name\");\n      }\n\n      if (vc.getOutputName().equals(ColumnHolder.TIME_COLUMN_NAME)) {\n        throw new IAE(\"virtualColumn name[%s] not allowed\", vc.getOutputName());\n      }\n\n      if (withDotSupport.containsKey(vc.getOutputName()) || withoutDotSupport.containsKey(vc.getOutputName())) {\n        throw new IAE(\"Duplicate virtualColumn name[%s]\", vc.getOutputName());\n      }\n\n      if (vc.usesDotNotation()) {\n        withDotSupport.put(vc.getOutputName(), vc);\n      } else {\n        withoutDotSupport.put(vc.getOutputName(), vc);\n      }\n    }\n    return new VirtualColumns(ImmutableList.copyOf(virtualColumns), withDotSupport, withoutDotSupport);\n  }\n\n  public static VirtualColumns nullToEmpty(@Nullable VirtualColumns virtualColumns)\n  {\n    return virtualColumns == null ? EMPTY : virtualColumns;\n  }\n\n  // For equals, hashCode, toString, and serialization:\n  private final List<VirtualColumn> virtualColumns;","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/VirtualColumns.java#L102-L138","documentation":"Each VirtualColumn in a query must have a unique output name. fromIterable tracks names in maps and throws IAE when a duplicate name is encountered, because duplicated names would make column resolution ambiguous.","triggerScenarios":"Calling VirtualColumns.fromIterable/create with two virtual columns sharing the same output name — e.g. two expression columns both named \"v_expr\", or an expression and lookup column with identical names.","commonSituations":"Query builders appending columns without deduplicating; merging query fragments client-side; copy-pasted query JSON reusing a name.","solutions":["Rename the duplicate virtual columns to unique output names","Deduplicate the virtualColumns list before building the query (e.g. by name using LinkedHashMap)","Fix query-generation code to suffix names (v_expr_1, v_expr_2) when generating multiple columns"],"exampleFix":"// before\ncolumns.add(new ExpressionVirtualColumn(\"v_x\", \"x * 2\", ValueType.LONG, macros));\ncolumns.add(new ExpressionVirtualColumn(\"v_x\", \"x * 3\", ValueType.LONG, macros));\n// after\ncolumns.add(new ExpressionVirtualColumn(\"v_x_double\", \"x * 2\", ValueType.LONG, macros));\ncolumns.add(new ExpressionVirtualColumn(\"v_x_triple\", \"x * 3\", ValueType.LONG, macros));","handlingStrategy":"validation","validationCode":"Set<String> seen = new HashSet<>();\nfor (VirtualColumn vc : virtualColumns) {\n  if (!seen.add(vc.getOutputName())) {\n    throw new IllegalArgumentException(\"Duplicate virtual column name: \" + vc.getOutputName());\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  VirtualColumns.fromIterable(cols);\n} catch (IAE e) {\n  log.error(e, \"Duplicate virtual column names in query\");\n}","preventionTips":["Deduplicate virtualColumns by outputName before query construction","Use unique generated names (suffix counters) in query builders","Review hand-written query JSON for repeated names"],"tags":["virtual-column","duplicate-name","query"],"backgroundTag":"invalid-argument-value","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"}