prestodb/presto · error · PrestoException
INVALID_FUNCTION_ARGUMENT
INVALID_FUNCTION_ARGUMENT
Error message
ROW index out of bounds:
What it means
Subscript ([]) on a ROW value is evaluated manually; it throws INVALID_FUNCTION_ARGUMENT when the 1-based index is outside the row's field count. Row subscripts must be between 1 and the number of fields.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/planner/ExpressionInterpreter.java:1256
}
Object index = process(node.getIndex(), context);
if (index == null) {
return null;
}
if ((index instanceof Long) && isArray(type(node.getBase()))) {
ArraySubscriptOperator.checkArrayIndex((Long) index);
}
if (hasUnresolvedValue(base, index)) {
return new SubscriptExpression(toExpression(base, type(node.getBase())), toExpression(index, type(node.getIndex())));
}
// Subscript on Row hasn't got a dedicated operator. It is interpreted by hand.
if (base instanceof SingleRowBlock) {
SingleRowBlock row = (SingleRowBlock) base;
int position = toIntExact((long) index - 1);
if (position < 0 || position >= row.getPositionCount()) {
throw new PrestoException(StandardErrorCode.INVALID_FUNCTION_ARGUMENT, "ROW index out of bounds: " + (position + 1));
}
Type returnType = type(node.getBase()).getTypeParameters().get(position);
return TypeUtils.readNativeValue(returnType, row, position);
}
// Subscript on Array or Map is interpreted using operator.
return invokeOperator(OperatorType.SUBSCRIPT, types(node.getBase(), node.getIndex()), ImmutableList.of(base, index));
}
@Override
protected Object visitQuantifiedComparisonExpression(QuantifiedComparisonExpression node, Object context)
{
if (!optimize) {
throw new UnsupportedOperationException("QuantifiedComparison not yet implemented");
}
return node;
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Validate the subscript is within 1..cardinality(row) before applying it.
- Use a CASE/TRY expression to guard out-of-range indexes.
- Fix off-by-one index computation (Presto ROW subscripts are 1-based).
Example fix
// before SELECT r[2] FROM t; // after SELECT IF(cardinality(r) >= 2, r[2], NULL) FROM t;
Defensive patterns
Strategy: validation
Validate before calling
if (index < 1 || index > cardinality(rowValue)) { return null; } // 1-based ROW subscript check Type guard
boolean inRowRange(int index, int positionCount) { return index >= 1 && index <= positionCount; } Try / catch
try { return exprInterpreter.evaluate(rowSubscriptExpr, context); } catch (PrestoException e) { if (e.getErrorCode() == StandardErrorCode.INVALID_FUNCTION_ARGUMENT.toErrorCode()) { return null; } throw e; } Prevention
- Remember ROW subscripts are 1-based
- Guard dynamic subscripts with cardinality() checks
- Wrap risky expressions in TRY() in SQL
When it happens
Trigger: Evaluating row_col[i] where i < 1 or i > number of row fields during constant folding or non-vectorized expression evaluation.
Common situations: Dynamic indexes computed from data that can exceed the row arity, off-by-one mistakes (index 0), or empty-row edge cases in UDF-generated values.
Related errors
- Invalid position %s and length %s in page with %s positions
- Invalid channel %d in page with %s channels
- Invalid position %s and length %s in block with %s positions
- Invalid row block:
- Invalid row block
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/1b468dd28d55d41b.
Report an issue: GitHub.