apache/druid · error · IllegalArgumentException

Must have at least one input channel

Error message

Must have at least one input channel

What it means

FrameChannelMerger merges multiple sorted Frame input channels into one sorted output. Merging is meaningless with zero inputs, so the constructor throws IAE when the inputChannels collection is empty. This is an upfront contract check: callers must supply at least one ReadableFrameChannel.

Source

Thrown at processing/src/main/java/org/apache/druid/frame/processor/FrameChannelMerger.java:114

   * @param sortKey            sort key for input and output frames
   * @param combiner           optional combiner for merging rows with identical sort keys
   * @param partitions         partitions for output frames. If non-null, output frames are written with
   *                           partition numbers set according to this parameter
   * @param rowLimit           maximum number of rows to write to the output channel
   */
  public FrameChannelMerger(
      final List<ReadableFrameChannel> inputChannels,
      final FrameReader frameReader,
      final WritableFrameChannel outputChannel,
      final FrameWriterFactory frameWriterFactory,
      final List<KeyColumn> sortKey,
      @Nullable final FrameCombiner combiner,
      @Nullable final ClusterByPartitions partitions,
      final long rowLimit
  )
  {
    if (inputChannels.isEmpty()) {
      throw new IAE("Must have at least one input channel");
    }

    final ClusterByPartitions partitionsToUse =
        partitions == null ? ClusterByPartitions.oneUniversalPartition() : partitions;

    if (!partitionsToUse.allAbutting()) {
      // To simplify merging logic, when frames we only look at the earliest and latest key in "partitions". To ensure
      // correctness, we need to verify that there are no gaps.
      throw new IAE("Partitions must all abut each other");
    }

    if (!sortKey.stream().allMatch(keyColumn -> keyColumn.order().sortable())) {
      throw new IAE("Key is not sortable");
    }

    this.inputChannels = inputChannels;
    this.outputChannel = outputChannel;
    this.frameReader = frameReader;

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Ensure at least one input channel is provided; if a stage may legitimately have zero inputs, skip the merge rather than constructing a merger.
  2. Guard the call: only create FrameChannelMerger when inputChannels.size() >= 1.
  3. Trace why upstream partitioning produced zero channels (empty partition bound set) and fix the producer.

Example fix

// before
FrameChannelMerger merger = new FrameChannelMerger(allocator, sortKey, channels, null, partitions, rowLimit);
// after
if (channels.isEmpty()) {
  return; // nothing to merge
}
FrameChannelMerger merger = new FrameChannelMerger(allocator, sortKey, channels, null, partitions, rowLimit);
Defensive patterns

Strategy: type-guard

Validate before calling

if (inputChannels == null || inputChannels.isEmpty()) {
  throw new IllegalStateException("Cannot merge: no input channels");
}

Type guard

boolean canMerge(List<ReadableFrameChannel> channels) { return channels != null && !channels.isEmpty(); }

Try / catch

try {
  merger = new FrameChannelMerger(allocator, sortKey, channels, null, partitions, rowLimit);
} catch (IllegalArgumentException e) {
  // zero inputs: skip merge or fail the stage with context
}

Prevention

When it happens

Trigger: Calling `new FrameChannelMerger(allocator, sortKey, List.of(), combiner, partitions, rowLimit)` or passing a channel list that ended up empty after filtering/partitioning produced no partitions.

Common situations: Query-stage code that builds merger inputs from a partition bound set which is empty; filtering channels before merge removed all of them; bugs where a stage receives no work items and still attempts to construct a merger.

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/2660d3e62df4893f. Report an issue: GitHub.