apache/druid · error · IllegalStateException

Got a [ ] which isn't a

Error message

Got a [%s] which isn't a %s

What it means

SearchQueryRunner.run() requires the query inside QueryPlus to be a SearchQuery; anything else throws ISE('Got a [%s] which isn't a %s'). This is an internal type invariant at the segment runner level, mirroring the toolchest check at SearchQueryQueryToolChest.run(). It indicates the search runner received a misrouted query object.

Solutions

  1. Route only SearchQuery instances to SearchQueryRunner
  2. Correct custom QueryToolChest/warehouse wiring so query types map to their proper runners
  3. Unwrap or convert the query to SearchQuery before invoking the runner

Example fix

// before
searchRunner.run(QueryPlus.wrap(otherQuery), responseContext);
// after
if (otherQuery instanceof SearchQuery) {
  searchRunner.run(QueryPlus.wrap((Query<Result<SearchResultValue>>) otherQuery), responseContext);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(query instanceof SearchQuery)) { throw new IllegalArgumentException("SearchQueryRunner requires SearchQuery, got " + query.getClass()); }

Type guard

Optional<SearchQuery> asSearchQuery(Query<?> q) { return q instanceof SearchQuery ? Optional.of((SearchQuery) q) : Optional.empty(); }

Try / catch

try { return searchRunner.run(queryPlus, ctx); } catch (ISE e) { if (e.getMessage().startsWith("Got a [")) { fixQueryRouting(); } else throw e; }

Prevention

When it happens

Trigger: Custom runner chains passing a non-SearchQuery to SearchQueryRunner; toolchest mapping that binds SearchQueryRunner to the wrong query class; programmatically wrapping queries incorrectly.

Common situations: Custom extension runner stacks; reflection-based query construction losing type; test harnesses assembling QueryPlus manually with the wrong query.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/query/search/SearchQueryRunner.java:218

    {
      if (selector != null) {
        final String dimVal = selector.isNull() ? null : String.valueOf(selector.getDouble());
        if (searchQuerySpec.accept(dimVal)) {
          set.addTo(new SearchHit(outputName, dimVal), 1);
        }
      }
    }
  }

  @Override
  public Sequence<Result<SearchResultValue>> run(
      final QueryPlus<Result<SearchResultValue>> queryPlus,
      ResponseContext responseContext
  )
  {
    Query<Result<SearchResultValue>> input = queryPlus.getQuery();
    if (!(input instanceof SearchQuery)) {
      throw new ISE("Got a [%s] which isn't a %s", input.getClass(), SearchQuery.class);
    }

    final SearchQuery query = (SearchQuery) input;
    final List<SearchQueryExecutor> plan = strategySelector.strategize(query).getExecutionPlan(query, segment);
    final Object2IntRBTreeMap<SearchHit> retVal = new Object2IntRBTreeMap<>(query.getSort().getComparator());
    retVal.defaultReturnValue(0);

    int remain = query.getLimit();
    for (final SearchQueryExecutor executor : plan) {
      retVal.putAll(executor.execute(remain));
      remain -= retVal.size();
    }

    return makeReturnResult(segment, query.getLimit(), retVal);
  }

  private static Sequence<Result<SearchResultValue>> makeReturnResult(
      Segment segment,

View on GitHub (pinned to 9b90983fd2)