apache/druid · error · IllegalStateException

Cannot call get() before aggregate()

Error message

Cannot call get() before aggregate()

What it means

PassthroughAggregator.get() is a state guard: the aggregator buffers the selected object in aggregate() (setting didSet), and get() before any aggregate() call would return an uninitialized value, so it throws ISE. Indicates the aggregation framework finalized/read the aggregator out of order.

Solutions

  1. Report as a bug with the query and aggregator configuration; the framework should always call aggregate() before get().
  2. Check whether custom aggregator code or an unusual query shape (e.g. empty result rows) reaches get() before aggregation.

Example fix

// before
Object v = agg.get(); // ISE if never aggregated
// after
if (agg instanceof PassthroughAggregator) { agg.aggregate(); }
Object v = agg.get();
Defensive patterns

Strategy: type-guard

Validate before calling

// aggregate at least once before reading
if (rows.isEmpty()) { throw new IllegalStateException("No rows; aggregator never aggregated"); }

Type guard

// can only be checked post-aggregation; ensure lifecycle
boolean canGet(PassthroughAggregator a) { a.aggregate(); return true; }

Try / catch

try {
  Object v = aggregator.get();
} catch (ISE e) {
  if (e.getMessage().contains("before aggregate")) { /* aggregate first or treat as no data */ }
  else throw e;
}

Prevention

When it happens

Trigger: Query engine or test code calls get()/getFloat()/etc. before invoking aggregate() at least once on the aggregator instance.

Common situations: Custom aggregation code or a unit test retrieving the result of an aggregator that never aggregated; engine bug where the aggregator was never driven.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/util/PassthroughAggregator.java:55

  }

  @Override
  public void aggregate()
  {
    if (didSet) {
      throw new ISE("Cannot set twice");
    }

    val = selector.getObject();
    didSet = true;
  }

  @Nullable
  @Override
  public Object get()
  {
    if (!didSet) {
      throw new ISE("Cannot call get() before aggregate()");
    }

    return val;
  }

  @Override
  public float getFloat()
  {
    throw new UnsupportedOperationException();
  }

  @Override
  public long getLong()
  {
    throw new UnsupportedOperationException();
  }

  @Override

View on GitHub (pinned to 9b90983fd2)