{"record":{"id":"296c3fe46a6cb1b1","repo":"apache/druid","slug":"cannot-have-duplicate-field-definition-s","errorCode":null,"errorMessage":"Cannot have duplicate field definition: %s","messagePattern":"Cannot have duplicate field definition: (.+?)","errorType":"validation","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/java/util/common/parsers/ObjectFlatteners.java","lineNumber":77,"sourceCode":"      switch (fieldSpec.getType()) {\n        case ROOT:\n          extractor = obj -> flattenerMaker.getRootField(obj, fieldSpec.getExpr());\n          break;\n        case PATH:\n          extractor = flattenerMaker.makeJsonPathExtractor(fieldSpec.getExpr());\n          break;\n        case JQ:\n          extractor = flattenerMaker.makeJsonQueryExtractor(fieldSpec.getExpr());\n          break;\n        case TREE:\n          extractor = flattenerMaker.makeJsonTreeExtractor(fieldSpec.getNodes());\n          break;\n        default:\n          throw new UOE(\"Unsupported field type[%s]\", fieldSpec.getType());\n      }\n\n      if (extractors.put(fieldSpec.getName(), extractor) != null) {\n        throw new IAE(\"Cannot have duplicate field definition: %s\", fieldSpec.getName());\n      }\n    }\n\n    return new ObjectFlattener<>()\n    {\n      @Override\n      public Map<String, Object> flatten(final T obj)\n      {\n        return new AbstractMap<>()\n        {\n          @Override\n          public int size()\n          {\n            return keySet().size();\n          }\n\n          @Override\n          public boolean isEmpty()","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/java/util/common/parsers/ObjectFlatteners.java#L59-L95","documentation":"ObjectFlatteners.create() keeps a Map of field name -> extractor; putting a second extractor under a name that already exists returns non-null and triggers this IAE. Two fieldSpec entries in the same flattenSpec must not share the same 'name'.","triggerScenarios":"Passing a flattenSpec whose 'flattener' list contains two or more fieldSpecs with identical 'name' values to ObjectFlatteners.create().","commonSituations":"Copy-pasted fieldSpec entries with the name not updated after changing the expr; programmatically merging specs from two sources that both define the same output column; templated spec generation producing duplicate names.","solutions":["Remove or rename the duplicate fieldSpec entry so every fieldSpec has a unique 'name'","Deduplicate the flattener list before building the spec (e.g. by field name, keeping the last/first occurrence intentionally)","Log or assert spec uniqueness in spec-generation tooling"],"exampleFix":"// before\n[{\"type\":\"path\",\"name\":\"val\",\"expr\":\"$.a\"},{\"type\":\"path\",\"name\":\"val\",\"expr\":\"$.b\"}]\n// after\n[{\"type\":\"path\",\"name\":\"val_a\",\"expr\":\"$.a\"},{\"type\":\"path\",\"name\":\"val_b\",\"expr\":\"$.b\"}]","handlingStrategy":"validation","validationCode":"Set<String> seen = new HashSet<>();\nfor (FieldSpec fs : flattenSpec.getFlattener()) {\n  if (!seen.add(fs.getName())) throw new IllegalArgumentException(\"duplicate fieldSpec name: \" + fs.getName());\n}","typeGuard":null,"tryCatchPattern":"try { flattener = ObjectFlatteners.create(spec, maker); } catch (IAE e) { throw new SpecValidationException(\"Duplicate field in flattenSpec\", e); }","preventionTips":["Ensure every fieldSpec name is unique before submitting the spec","Deduplicate generated specs by field name","Review copy-pasted entries for unchanged names"],"tags":["flatten-spec","duplicate-field","ingestion"],"backgroundTag":"schema-validation-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}