elastic/elasticsearch · error · IllegalArgumentException

[separator] must not be null: [${name}]

Error message

[separator] must not be null: [${name}]

What it means

Thrown by AdjacencyMatrixAggregationBuilder.separator(String) when the argument is null. The separator string is used to join pairs of bucket keys in the resulting matrix buckets; null would break key generation downstream, so the setter explicitly rejects it.

Source

Thrown at modules/aggregations/src/main/java/org/elasticsearch/aggregations/bucket/adjacency/AdjacencyMatrixAggregationBuilder.java:170

        // internally we want to have a fixed order of filters, regardless of
        // the order of the filters in the request
        this.filters.sort(Comparator.comparing(KeyedFilter::key));
    }

    private AdjacencyMatrixAggregationBuilder setFiltersAsList(List<KeyedFilter> filters) {
        this.filters = new ArrayList<>(filters);
        // internally we want to have a fixed order of filters, regardless of
        // the order of the filters in the request
        this.filters.sort(Comparator.comparing(KeyedFilter::key));
        return this;
    }

    /**
     * Set the separator used to join pairs of bucket keys
     */
    public AdjacencyMatrixAggregationBuilder separator(String separator) {
        if (separator == null) {
            throw new IllegalArgumentException("[separator] must not be null: [" + name + "]");
        }
        this.separator = separator;
        return this;
    }

    /**
     * Get the filters. This will be an unmodifiable map
     */
    public Map<String, QueryBuilder> filters() {
        Map<String, QueryBuilder> result = Maps.newMapWithExpectedSize(this.filters.size());
        for (KeyedFilter keyedFilter : this.filters) {
            result.put(keyedFilter.key(), keyedFilter.filter());
        }
        return result;
    }

    @Override
    protected AdjacencyMatrixAggregationBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Default to the standard separator ("&") when the input is null: `separator(s == null ? "&" : s)`.
  2. Validate upstream that separator is non-null before calling the builder.
  3. Use an Optional/Objects.requireNonNull on the source value with a sensible default.

Example fix

// before
builder.separator(maybeNull);
// after
import java.util.Objects;
builder.separator(Objects.requireNonNullElse(maybeNull, "&"));
Defensive patterns

Strategy: validation

Validate before calling

String sep = Objects.requireNonNullElse(candidateSeparator, "&");
builder.separator(sep);

Prevention

When it happens

Trigger: Calling `.separator(null)` on an adjacency_matrix aggregation builder. Programmatic code passing a possibly-null variable without null-checking. Deserialization paths that resolve separator from an absent optional field as null.

Common situations: Wrapping an optional user input directly into separator() without defaulting. Refactoring that introduces a nullable source for the separator. Tests that pass null to verify behavior.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/495b91b02ace3e21. Report an issue: GitHub.