{"record":{"id":"4b7b5e7792cdc59a","repo":"apache/druid","slug":"cannot-make-array-element-selector-negative-array","errorCode":null,"errorMessage":"Cannot make array element selector, negative array index not supported","messagePattern":"Cannot make array element selector, negative array index not supported","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/virtual/NestedFieldVirtualColumn.java","lineNumber":318,"sourceCode":"      if (theColumn instanceof DictionaryEncodedColumn) {\n        final DictionaryEncodedColumn<?> column = (DictionaryEncodedColumn<?>) theColumn;\n        return new BestEffortCastingValueSelector(column.makeDimensionSelector(offset, extractionFn));\n      } else {\n        // for non-dictionary encoded columns, wrap a value selector to make it appear as a dimension selector\n        return ValueTypes.makeNumericWrappingDimensionSelector(\n            holder.getCapabilities().getType(),\n            selectorFactory.makeColumnValueSelector(fieldSpec.columnName),\n            extractionFn\n        );\n      }\n    }\n\n    if (isRootArrayElementPathAndArrayColumn(theColumn)) {\n      final VariantColumn<?> arrayColumn = (VariantColumn<?>) theColumn;\n      ColumnValueSelector<?> arraySelector = arrayColumn.makeColumnValueSelector(offset);\n      final int elementNumber = ((NestedPathArrayElement) fieldSpec.parts.get(0)).getIndex();\n      if (elementNumber < 0) {\n        throw new IAE(\"Cannot make array element selector, negative array index not supported\");\n      }\n      return new BaseSingleValueDimensionSelector()\n      {\n        @Nullable\n        @Override\n        protected String getValue()\n        {\n          Object o = arraySelector.getObject();\n          if (o instanceof Object[]) {\n            Object[] array = (Object[]) o;\n            if (elementNumber < array.length) {\n              Object element = array[elementNumber];\n              if (element == null) {\n                return null;\n              }\n              return String.valueOf(element);\n            }\n          }","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/virtual/NestedFieldVirtualColumn.java#L300-L336","documentation":"When a nested field path is just a root array element (e.g. '$[0]') on an array-typed column, makeDimensionSelectorUndecorated extracts that element; a negative index cannot name an array element, so it throws IAE. This guards against malformed path specs reaching selector creation.","triggerScenarios":"NestedFieldVirtualColumn with pathParts = [NestedPathArrayElement(-1)] (or jq path resolving to negative index) used in a dimension selector query on an array column.","commonSituations":"Programmatic path construction computing an index that can be negative (e.g. subtracting to index from the end); hand-written jq path where the parser produced a negative part index.","solutions":["Use a non-negative array index (0-based) in the path, e.g. '$[0]'","Compute the index defensively: Math.max(0, index) or validate before building NestedPathArrayElement","If negative-from-end indexing was intended, rewrite the expression to compute the element differently (e.g. ARRAY_ORDINAL with reverse)"],"exampleFix":"// before\nnew NestedFieldVirtualColumn(\"arr\", \"first\", null, Collections.singletonList(new NestedPathArrayElement(-1)), null, null, null);\n// after\nnew NestedFieldVirtualColumn(\"arr\", \"first\", null, Collections.singletonList(new NestedPathArrayElement(0)), null, null, null);","handlingStrategy":"validation","validationCode":"int idx = ((NestedPathArrayElement) parts.get(0)).getIndex();\nif (idx < 0) throw new IllegalArgumentException(\"Array index must be >= 0\");","typeGuard":"boolean ok = part instanceof NestedPathArrayElement && ((NestedPathArrayElement) part).getIndex() >= 0;","tryCatchPattern":"try { col.makeDimensionSelector(spec, offset); } catch (IllegalArgumentException e) { /* clamp index and retry */ }","preventionTips":["Validate path part indices when building NestedPathArrayElement programmatically","Use 0-based positive indices; jq '$[0]' not '$[-1]'","Clamp computed indices with Math.max(0, idx)"],"tags":["virtual-column","nested-fields","array-index","illegal-argument"],"backgroundTag":"index-out-of-range","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"}