apache/druid · error · IAE

Unknown type for input

Error message

Unknown type for input[%s]

What it means

TopNResultValue.fromObject builds a Function that converts each row of a topN result into a DimensionAndMetricValueExtractor. Each row must be either a Map or already a DimensionAndMetricValueExtractor; anything else (e.g. a List, String, or custom POJO) triggers this IllegalArgumentException.

Solutions

  1. Convert each result row to a Map<String,Object> (e.g. with an object mapper's convertValue(row, Map.class)) before passing to TopNResultValue.fromObject
  2. If you already have extractors, wrap them in DimensionAndMetricValueExtractor directly
  3. Check custom code that reshapes topN results and make it emit maps keyed by dimension/metric names

Example fix

// before
List<Object> rows = Arrays.asList(Arrays.asList("dim", 42));
TopNResultValue value = TopNResultValue.fromObject(rows);
// after
List<Object> rows = Arrays.asList(ImmutableMap.of("dimension", "dim", "metric", 42));
TopNResultValue value = TopNResultValue.fromObject(rows);
Defensive patterns

Strategy: validation

Validate before calling

for (Object row : rows) {
  if (!(row instanceof Map || row instanceof DimensionAndMetricValueExtractor)) {
    throw new IllegalArgumentException("topN row must be a Map or DimensionAndMetricValueExtractor: " + row.getClass());
  }
}

Type guard

static boolean isValidTopNRow(Object row) {
  return row instanceof Map || row instanceof DimensionAndMetricValueExtractor;
}

Try / catch

try {
  TopNResultValue value = TopNResultValue.fromObject(rows);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Unknown type for input")) {
    rows = rows.stream().map(r -> objectMapper.convertValue(r, Map.class)).collect(Collectors.toList());
    value = TopNResultValue.fromObject(rows);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling TopNResultValue.fromObject with a List whose elements are neither Map nor DimensionAndMetricValueExtractor — e.g. feeding raw arrays, JSON-decoded lists, or custom result objects into the topN result post-processing path; custom query tool chests or federation code that reshapes topN rows incorrectly.

Common situations: Custom query runners emitting topN rows as Java beans or JSON arrays; downstream extension code (e.g. custom federation or rewrite layers) that mangles row structure; deserialization producing List<List<Object>> instead of List<Map<String,Object>>.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/query/topn/TopNResultValue.java:56

{
  private final List<DimensionAndMetricValueExtractor> valueList;

  @JsonCreator
  public static TopNResultValue create(List<?> value)
  {
    if (value == null) {
      return new TopNResultValue(new ArrayList<>());
    }

    return new TopNResultValue(Lists.transform(
        value,
        (Function<Object, DimensionAndMetricValueExtractor>) input -> {
          if (input instanceof Map) {
            return new DimensionAndMetricValueExtractor((Map) input);
          } else if (input instanceof DimensionAndMetricValueExtractor) {
            return (DimensionAndMetricValueExtractor) input;
          } else {
            throw new IAE("Unknown type for input[%s]", input.getClass());
          }
        }
    ));
  }

  public TopNResultValue(List<DimensionAndMetricValueExtractor> valueList)
  {
    this.valueList = valueList;
  }

  @JsonValue
  public List<DimensionAndMetricValueExtractor> getValue()
  {
    return valueList;
  }

  @Override
  public Iterator<DimensionAndMetricValueExtractor> iterator()

View on GitHub (pinned to 9b90983fd2)