apache/druid · error · IllegalArgumentException

Must have at least one element

Error message

Must have at least one element

What it means

TournamentTree is a tournament tree used to merge at least two sorted streams. The constructor requires numElements >= 1; building a tree with zero elements is a programming error because the tree would have no leaves to pop from. IAE signals an invalid argument to the constructor.

Solutions

  1. Guard the element count and skip creating a TournamentTree when there are no inputs; return an empty result directly
  2. Ensure the upstream pipeline always yields at least one channel before merging
  3. If the count comes from a computed variable, log/inspect it before construction

Example fix

// before
TournamentTree tree = new TournamentTree(channels.size(), comparator);
// after
if (channels.isEmpty()) {
  return Collections.emptyListIterator();
}
TournamentTree tree = new TournamentTree(channels.size(), comparator);
Defensive patterns

Strategy: validation

Validate before calling

if (inputs.size() < 1) { return emptyResult(); }

Type guard

boolean canBuildTree(List<?> inputs) { return inputs != null && !inputs.isEmpty(); }

Try / catch

try { new TournamentTree(n, cmp); } catch (IllegalArgumentException e) { /* handle empty input path */ }

Prevention

When it happens

Trigger: Constructing new TournamentTree(0, comparator) — i.e., creating a merge tree over an empty set of channels/batches, such as when a sort/merge pipeline computes zero input channels.

Common situations: Empty partition or zero-batch result sets being fed into the frame merge machinery; off-by-one when computing channel counts in custom frame processors.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/frame/processor/TournamentTree.java:81

   * Comparator for the elements of the tree.
   */
  private final IntComparator comparator;

  /**
   * Whether this tree has been initialized.
   */
  private boolean initialized;

  /**
   * Creates a tree with a certain number of elements.
   *
   * @param numElements number of elements in the tree
   * @param comparator  comparator for the elements. Smaller elements "win".
   */
  public TournamentTree(final int numElements, final IntComparator comparator)
  {
    if (numElements < 1) {
      throw new IAE("Must have at least one element");
    }

    this.numElements = numElements;
    this.numElementsRounded = HashCommon.nextPowerOfTwo(numElements);
    this.comparator = comparator;
    this.tree = new int[numElementsRounded];
  }

  /**
   * Get the current minimum element (the overall winner, i.e., the run to pull the next element from in the
   * K-way merge).
   */
  public int getMin()
  {
    if (!initialized) {
      // Defer initialization until the first getMin() call, since the tree object might be created before the
      // comparator is fully valid. (The comparator is typically not valid until at least one row is available
      // from each run.)

View on GitHub (pinned to 9b90983fd2)