apache/druid · error · java.lang.UnsupportedOperationException
StringFirstAggregator does not support getLong()
Error message
StringFirstAggregator does not support getLong()
What it means
StringLastBufferAggregator cannot produce a long from its stored timestamp/string pair, so getLong(ByteBuffer,int) throws UnsupportedOperationException. This enforces that string aggregators are consumed through their string result path.
Source
Thrown at processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastBufferAggregator.java:121
}
}
@Override
public Object get(ByteBuffer buf, int position)
{
return StringFirstLastUtils.readPair(buf, position);
}
@Override
public float getFloat(ByteBuffer buf, int position)
{
throw new UnsupportedOperationException("StringFirstAggregator does not support getFloat()");
}
@Override
public long getLong(ByteBuffer buf, int position)
{
throw new UnsupportedOperationException("StringFirstAggregator does not support getLong()");
}
@Override
public double getDouble(ByteBuffer buf, int position)
{
throw new UnsupportedOperationException("StringFirstAggregator does not support getDouble()");
}
@Override
public void close()
{
// no resources to cleanup
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector)
{
inspector.visit("timeSelector", timeSelector);View on GitHub (pinned to 9b90983fd2)
Solutions
- Extract the value via get(ByteBuffer,int) (the string pair) instead of getLong
- Choose a numeric aggregator (longFirst/longLast) when a long is needed
- Check AggregatorFactory.getTypeName() and only call the matching typed accessor
- Apply SQL CAST(... AS BIGINT) if the string should be interpreted as a long
Example fix
// before long l = bufAgg.getLong(buf, position); // throws // after Object val = bufAgg.get(buf, position); // string result long l2 = Long.parseLong((String) val); // only if conversion intended
Defensive patterns
Strategy: type-guard
Validate before calling
if ("long".equals(factory.getTypeName())) { l = bufAgg.getLong(buf, pos); } else { /* string path */ } Type guard
static boolean hasLongAccessor(AggregatorFactory f) { return f.getTypeName().equals("long"); } Try / catch
try { l = bufAgg.getLong(buf, pos); } catch (UnsupportedOperationException e) { l = 0L; } Prevention
- Check the metric type before integer result extraction
- Use longFirst/longLast for integer aggregations
- Convert string results explicitly (parseLong) when numeric output is intended
When it happens
Trigger: Calling getLong(buf, position) on a StringLastBufferAggregator instance during result collection when the metric is assumed numeric.
Common situations: Generic result merge/extraction code in custom extensions; tests that call all three numeric accessors on every buffer aggregator; SQL plans that expect a numeric type but were given stringFirst/stringLast.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- StringFirstAggregator does not support getFloat()
- StringFirstAggregator does not support getDouble()
- Not implemented
- Not implemented
- ApproximateHistogramBufferAggregator does not support getFlo
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/336143f56240be4d.
Report an issue: GitHub.