apache/druid · error · ExpressionValidationException
needs a number as its first argument but got %s instead
Error message
needs a number as its first argument but got %s instead
What it means
Thrown by Druid's HUMAN_READABLE_BYTES_FORMAT expression function when the first argument (the byte count to format) is neither LONG nor DOUBLE at validation time. Only numeric values are accepted; a DOUBLE is cast to LONG before formatting.
Source
Thrown at processing/src/main/java/org/apache/druid/math/expr/Function.java:4677
abstract class SizeFormatFunc implements Function
{
protected abstract HumanReadableBytes.UnitSystem getUnitSystem();
@Override
public ExprEval apply(List<Expr> args, Expr.ObjectBinding bindings)
{
final ExprEval valueParam = args.get(0).eval(bindings);
if (valueParam.isNumericNull()) {
return ExprEval.ofString(null);
}
/**
* only LONG and DOUBLE are allowed
* For a DOUBLE, it will be cast to LONG before format
*/
if (valueParam.value() != null && !valueParam.type().anyOf(ExprType.LONG, ExprType.DOUBLE)) {
throw validationFailed(
"needs a number as its first argument but got %s instead",
valueParam.type()
);
}
/**
* By default, precision is 2
*/
long precision = 2;
if (args.size() > 1) {
ExprEval precisionParam = args.get(1).eval(bindings);
if (precisionParam.value() == null) {
throw validationFailed("needs a LONG as its second argument but got null");
}
if (!precisionParam.type().is(ExprType.LONG)) {
throw validationFailed("needs a LONG as its second argument but got %s instead", precisionParam.type());
}
precision = precisionParam.asLong();View on GitHub (pinned to 9b90983fd2)
Solutions
- Cast the first argument: CAST(size_bytes AS BIGINT) before calling the function.
- Use a numeric literal instead of a quoted one, e.g. human_readable_bytes_format(1024).
- Fix ingestion/rollup typing so the column is stored as LONG.
- Validate the expression type in a dry-run/EXPLAIN PLAN before running the query.
Example fix
// before human_readable_bytes_format(byte_str) // after human_readable_bytes_format(CAST(byte_str AS BIGINT))
Defensive patterns
Strategy: validation
Validate before calling
CAST(size_expr AS BIGINT) -- apply before human_readable_bytes_format
Type guard
// only allow numeric args
if (!(v instanceof Number)) throw new IllegalArgumentException("byte count must be numeric"); Prevention
- Cast string-typed size columns at ingestion time
- Use numeric literals, not quoted numbers
- Verify types with EXPLAIN PLAN
When it happens
Trigger: Calling human_readable_bytes_format with a STRING, BOOLEAN, or other non-numeric first argument, e.g. human_readable_bytes_format('1024') where the string was never cast.
Common situations: Ingested size fields stored as strings (CSV/JSON inputs); users forgetting CAST(col AS BIGINT); binding parameters typed as strings from client frameworks.
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
- needs a LONG as its second argument but got %s instead
- Cannot implicitly cast [%s] to [%s]
- first argument must be constant STRING expression containing
- second argument must be a base64 encoded STRING value but go
- Cannot cast [%s] to [%s] (Types.InvalidCastException from in
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/e805831583706561.
Report an issue: GitHub.