{"record":{"id":"fa4c78adedea5a11","repo":"apache/druid","slug":"expected-a-number-or-an-instance-of-mergingdigest","errorCode":null,"errorMessage":"Expected a number or an instance of MergingDigest, but received [%s] of type [%s]","messagePattern":"Expected a number or an instance of MergingDigest, but received \\[(.+?)\\] of type \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions-contrib/tdigestsketch/src/main/java/org/apache/druid/query/aggregation/tdigestsketch/TDigestSketchAggregator.java","lineNumber":73,"sourceCode":"  }\n\n  @Override\n  public void aggregate()\n  {\n    Object obj = selector.getObject();\n    if (obj == null) {\n      return;\n    }\n    if (obj instanceof Number) {\n      synchronized (this) {\n        histogram.add(((Number) obj).doubleValue());\n      }\n    } else if (obj instanceof MergingDigest) {\n      synchronized (this) {\n        histogram.add((MergingDigest) obj);\n      }\n    } else {\n      throw new IAE(\n          \"Expected a number or an instance of MergingDigest, but received [%s] of type [%s]\",\n          obj,\n          obj.getClass()\n      );\n    }\n  }\n\n  @Nullable\n  @Override\n  public synchronized Object get()\n  {\n    return histogram;\n  }\n\n  @Override\n  public float getFloat()\n  {\n    throw new UnsupportedOperationException(\"Casting to float type is not supported\");","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-contrib/tdigestsketch/src/main/java/org/apache/druid/query/aggregation/tdigestsketch/TDigestSketchAggregator.java#L55-L91","documentation":"TDigestSketchAggregator's aggregate() accepts only numeric values (added as double data points) or MergingDigest instances (merged whole sketches). Any other object type in the selector is rejected with this IAE naming the value and its class.","triggerScenarios":"Feeding the tdigestsketch aggregator a column or expression that yields non-numeric, non-MergingDigest objects, e.g. string fields, HyperLogLog sketches, arrays, or serialized (non-deserialized) sketch representations.","commonSituations":"Pointing the aggregator at a raw string/complex column instead of a tdigestsketch column; a post-aggregator or expression outputting the wrong type; mixing aggregation on deserialized vs serialized sketch objects.","solutions":["Point the aggregator at a column of type tdigestsketch (MergingDigest values) or a numeric column.","If the value is serialized bytes, deserialize it first via TDigestSketchAggregatorFactory.deserialize / the sqlTypeName coercion.","Remove or fix the expression/post-aggregator that is emitting an unexpected type.","Check the input column's actual types with a small sample query before aggregating."],"exampleFix":"// before\nnew TDigestSketchAggregatorFactory(\"sk\", \"someStringColumn\", 100);\n// after\nnew TDigestSketchAggregatorFactory(\"sk\", \"tdigestColumn\", 100);","handlingStrategy":"type-guard","validationCode":"if (!(v instanceof Number || v instanceof MergingDigest)) { throw new IllegalArgumentException(\"column must be numeric or tdigestsketch, got: \" + v.getClass()); }","typeGuard":"boolean isAggregateable(Object v) { return v instanceof Number || v instanceof MergingDigest; }","tryCatchPattern":"try { agg.aggregate(selector); } catch (IAE e) { log.error(\"bad input to tdigest aggregator: %s\", e.getMessage()); }","preventionTips":["Bind the aggregator only to numeric or tdigestsketch-typed columns.","Sample the input column's types before running aggregations.","Avoid expressions that emit strings/arrays into sketch aggregators.","Deserialize serialized sketches before aggregating."],"tags":["java","druid","tdigest","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}