prestodb/presto · error · SemanticException
INVALID_OFFSET_ROW_COUNT
INVALID_OFFSET_ROW_COUNT
Error message
Invalid OFFSET row count: %s
What it means
Analysis error from analyzeOffset: the OFFSET row count string is not a valid integer literal (Long.parseLong failed). The OFFSET argument must be a plain non-negative integer constant; expressions, decimals, or non-numeric text trigger this guard.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java:5496
}
}
withScopeBuilder.withNamedQuery(name, withQuery);
}
Scope withScope = withScopeBuilder.build();
analysis.setScope(with, withScope);
return withScope;
}
private void analyzeOffset(Offset node)
{
long rowCount;
try {
rowCount = Long.parseLong(node.getRowCount());
}
catch (NumberFormatException e) {
throw new SemanticException(INVALID_OFFSET_ROW_COUNT, node, "Invalid OFFSET row count: %s", node.getRowCount());
}
if (rowCount < 0) {
throw new SemanticException(INVALID_OFFSET_ROW_COUNT, node, "OFFSET row count must be greater or equal to 0 (actual value: %s)", rowCount);
}
analysis.setOffset(node, rowCount);
}
private void verifySelectDistinct(QuerySpecification node, List<Expression> outputExpressions)
{
for (SortItem item : node.getOrderBy().get().getSortItems()) {
Expression expression = item.getSortKey();
if (expression instanceof LongLiteral) {
continue;
}
Expression rewrittenOrderByExpression = ExpressionTreeRewriter.rewriteWith(new OrderByExpressionRewriter(extractNamedOutputExpressions(node.getSelect())), expression);
int index = outputExpressions.indexOf(rewrittenOrderByExpression);View on GitHub (pinned to 55bb57d202)
Solutions
- Use a plain integer literal: OFFSET 10
- Fix the templating so the parameter substitutes a valid integer
- Validate user-provided page numbers are numeric before building SQL
- Note: a valid negative number is rejected separately (see next error), so also clamp to >= 0
Example fix
// before SELECT * FROM t OFFSET 'ten'; // after SELECT * FROM t OFFSET 10;
Defensive patterns
Strategy: validation
Validate before calling
if (!offsetStr.matches("\\d+")) throw new IllegalArgumentException("OFFSET must be a non-negative integer literal: " + offsetStr); Try / catch
try { runQuery(); } catch (SemanticException e) { if (e.getCode() == INVALID_OFFSET_ROW_COUNT.toErrorCode()) { sanitizeOffsetAndRetry(); } throw e; } Prevention
- Interpolate offsets only as validated integers
- Never quote the OFFSET literal
- Strip units/suffixes from user input before templating
When it happens
Trigger: SELECT * FROM t OFFSET 'abc'; or OFFSET with a non-integer literal token in the OFFSET clause.
Common situations: Templated SQL where a parameter renders as an empty or malformed string; users quoting the number; copy-paste leaving units like '10 rows' in the literal.
Related errors
- INVALID_TRANSACTION_MODE
- INVALID_FUNCTION_ARGUMENT
- INVALID_FUNCTION_ARGUMENT
- INVALID_LIMIT_CLAUSE
- NOT_SUPPORTED
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/e9c19aa5d4b11c05.
Report an issue: GitHub.