apache/druid · error · IllegalArgumentException
Expected a Number, but received [%s] of type [%s]
Error message
Expected a Number, but received [%s] of type [%s]
What it means
SpectatorHistogramAggregateHelper.merge combines the aggregator's current histogram with either another SpectatorHistogram or a single Number sample. Any other object type is unsupported and throws IAE naming the received value and its class. It is the helper's type contract for what can be folded into the aggregation.
Source
Thrown at extensions-contrib/spectator-histogram/src/main/java/org/apache/druid/spectator/histogram/SpectatorHistogramAggregateHelper.java:53
public void init(ByteBuffer buffer, int position)
{
SpectatorHistogram emptyCounts = new SpectatorHistogram();
addToCache(buffer, position, emptyCounts);
}
/**
* Merge obj ({@link SpectatorHistogram} or {@link Number}) into {@param current}.
*/
public void merge(SpectatorHistogram current, Object obj)
{
if (obj instanceof SpectatorHistogram) {
SpectatorHistogram other = (SpectatorHistogram) obj;
current.merge(other);
} else if (obj instanceof Number) {
current.insert((Number) obj);
} else {
throw new IAE(
"Expected a Number, but received [%s] of type [%s]",
obj,
obj.getClass()
);
}
}
/**
* Merge {@param value} into {@param current}.
*/
public void merge(SpectatorHistogram current, long value)
{
current.insert(value);
}
/**
* Fetches the SpectatorHistogram at the given buffer/position pair in the cache
*/View on GitHub (pinned to 9b90983fd2)
Solutions
- Verify the input column is numeric or of the spectator-histogram sketch type before aggregating.
- Cast or convert the object to Number / SpectatorHistogram before calling merge, or reject the row upstream.
- Check for serialization mismatches between writer and reader versions of the extension.
Example fix
// before
helper.merge(current, row.getRaw("metric")); // may be a String
// after
Object v = row.getRaw("metric");
if (v instanceof SpectatorHistogram || v instanceof Number) {
helper.merge(current, v);
} else {
throw new IAE("Unsupported metric type: " + v.getClass());
} Defensive patterns
Strategy: validation
Validate before calling
static boolean isMergeable(Object o) {
return o instanceof SpectatorHistogram || o instanceof Number;
} Type guard
static boolean isHistogramOrNumber(Object o) {
return o instanceof SpectatorHistogram || o instanceof Number;
} Try / catch
try {
helper.merge(current, obj);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Expected a Number")) {
log.warn("Skipping non-numeric input of type %s", obj.getClass());
return;
}
throw e;
} Prevention
- Bind the aggregator only to numeric metric columns or spectator-histogram sketch columns.
- Sanitize/transform rows so complex values never reach the metric slot.
- Add a pre-merge instanceof check in custom helpers.
When it happens
Trigger: A column or post-aggregator input yields a non-numeric, non-histogram object (e.g. String, Map, null-wrapped complex value) and the helper's merge(obj) is invoked on it during aggregation.
Common situations: Pointing the aggregator at a column of the wrong type (strings/dimensions instead of numeric metrics or histogram sketches); a serializer delivering a different sketch class; upstream filters or transforms emitting complex objects into the metric slot.
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
- Expected a number or an instance of DDSketch, but received [
- Expected a number or an instance of DDSketch, but received [
- Cannot add / to a Spectator Histogram
- Invalid input [%s] of type [%s] for [%s] aggregator [%s]
- Unsupported type %s
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/60a9722535a20e47.
Report an issue: GitHub.