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
- Guard the element count and skip creating a TournamentTree when there are no inputs; return an empty result directly
- Ensure the upstream pipeline always yields at least one channel before merging
- 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
- Check channel/input count before constructing merge structures
- Short-circuit empty-input pipelines
- Never compute numElements from possibly-empty collections without a guard
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
- bf1Length does not match bf2Length
- Adjacent intervals are not sorted
- AggregatorFactoryNotMergeableException
- AggregatorFactoryNotMergeableException
- AggregatorFactoryNotMergeableException(this, other)
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)