apache/druid · error · IllegalArgumentException

Must define exactly one of 'path' or 'pathParts'

Error message

Must define exactly one of 'path' or 'pathParts'

What it means

NestedFieldVirtualColumn extracts a nested field either via a jq-style 'path' string or a pre-parsed list of 'pathParts'; exactly one must be provided. Supplying neither (or the constructor seeing path==null and parts==null) throws IllegalArgumentException so a column with no way to locate the field is never created.

Solutions

  1. Set exactly one of 'path' (e.g. '$.a.b') or 'pathParts' in the virtual column spec
  2. Construct with NestedFieldVirtualColumn(String column, String outputName, String path, ...) or the parts-based constructor
  3. If both were supplied, remove one — note the related 'Cannot define both' check

Example fix

// before
{"type":"nested","column":"c","outputName":"o"} // no path/pathParts
// after
{"type":"nested","column":"c","outputName":"o","path":"$.a.b"}
Defensive patterns

Strategy: validation

Validate before calling

if ((path == null) == (pathParts == null)) {
  throw new IllegalArgumentException("Define exactly one of 'path' or 'pathParts'");
}

Type guard

boolean wellFormed = (path != null) ^ (pathParts != null);

Try / catch

try { new NestedFieldVirtualColumn(col, out, path, parts, useJq, null, null, null); } catch (IllegalArgumentException e) { /* repair spec */ }

Prevention

When it happens

Trigger: JSON spec for a nested field virtual column with only 'path' removed while 'pathParts' is also absent; programmatic construction passing null for both path and parts.

Common situations: Hand-edited virtual column JSON where 'path' was deleted; building the column in Java and forgetting to set either field; deserializing partial specs from older configs.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/3d3725ebce11e46a. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/segment/virtual/NestedFieldVirtualColumn.java:142

  private final boolean hasNegativeArrayIndex;

  @JsonCreator
  public NestedFieldVirtualColumn(
      @JsonProperty("columnName") String columnName,
      @JsonProperty("outputName") String outputName,
      @JsonProperty("expectedType") @Nullable ColumnType expectedType,
      @JsonProperty("pathParts") @Nullable List<NestedPathPart> parts,
      @JsonProperty("processFromRaw") @Nullable Boolean processFromRaw,
      @JsonProperty("path") @Nullable String path,
      @JsonProperty("useJqSyntax") @Nullable Boolean useJqSyntax
  )
  {
    this.outputName = outputName;
    if (path != null) {
      Preconditions.checkArgument(parts == null, "Cannot define both 'path' and 'pathParts'");
    } else if (parts == null) {
      throw new IllegalArgumentException("Must define exactly one of 'path' or 'pathParts'");
    }
    final List<NestedPathPart> pathParts;
    if (parts != null) {
      pathParts = parts;
    } else {
      boolean isInputJq = useJqSyntax != null && useJqSyntax;
      pathParts = isInputJq ? NestedPathFinder.parseJqPath(path) : NestedPathFinder.parseJsonPath(path);
    }
    boolean hasNegative = false;
    for (NestedPathPart part : pathParts) {
      if (part instanceof NestedPathArrayElement) {
        NestedPathArrayElement elementPart = (NestedPathArrayElement) part;
        if (elementPart.getIndex() < 0) {
          hasNegative = true;
          break;
        }
      }
    }

View on GitHub (pinned to 9b90983fd2)