prestodb/presto · error · IllegalArgumentException
VARCHAR length must be a number
Error message
VARCHAR length must be a number
What it means
The single VARCHAR type parameter must be an integer long literal, not a type parameter, wildcard, or named parameter. This is thrown when VARCHAR is given one parameter that is not a numeric length, e.g. VARCHAR(x) where x is a generic type parameter or VARCHAR(varchar(5)).
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/type/VarcharParametricType.java:50
public String getName()
{
return StandardTypes.VARCHAR;
}
@Override
public Type createType(List<TypeParameter> parameters)
{
if (parameters.isEmpty()) {
return createUnboundedVarcharType();
}
if (parameters.size() != 1) {
throw new IllegalArgumentException("Expected exactly one parameter for VARCHAR");
}
TypeParameter parameter = parameters.get(0);
if (!parameter.isLongLiteral()) {
throw new IllegalArgumentException("VARCHAR length must be a number");
}
long length = parameter.getLongLiteral();
if (length == VarcharType.UNBOUNDED_LENGTH) {
return VarcharType.createUnboundedVarcharType();
}
if (length < 0 || length > VarcharType.MAX_LENGTH) {
throw new IllegalArgumentException("Invalid VARCHAR length " + length);
}
return VarcharType.createVarcharType((int) length);
}
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Use a concrete integer length: VARCHAR(50).
- If writing generic functions, declare the length parameter separately via @LiteralParameters('x') and use varchar(x) in the @SqlType annotation instead of a non-long TypeParameter.
- Fix the connector metadata to emit long literals for VARCHAR lengths.
Example fix
// before
@SqlType("varchar(T)")
// after
@LiteralParameters("x")
@SqlType("varchar(x)") Defensive patterns
Strategy: validation
Validate before calling
boolean isValidVarcharParam(TypeParameter p) {
return p == null || p.isLongLiteral();
} Try / catch
try {
Type t = typeManager.getParameterizedType("varchar", params);
} catch (IllegalArgumentException e) {
// handle non-long-literal parameter: substitute a concrete length
} Prevention
- Always supply a numeric literal length for parameterized VARCHAR.
- For generic functions, use @LiteralParameters with varchar(x) annotations instead of type variables inside VARCHAR.
- Review plugin metadata generators for non-long TypeParameters.
When it happens
Trigger: Type signatures like VARCHAR(T) in a templated function declaration, VARCHAR(json) style misuse, or a connector that supplies a TypeParameter which is not a LongLiteral to createType.
Common situations: Writing parametric-type-aware custom functions with type variable placeholders copied incorrectly, plugin metadata generation bugs.
Related errors
- Expected exactly one parameter for VARCHAR
- TIMESTAMP precision must be in range [0, %d]: %d
- Invalid VARCHAR length
- dictionarySourceIds must be the same
- blocks is empty
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/75fa83b1c37b4fe2.
Report an issue: GitHub.