prestodb/presto · error · IllegalArgumentException

Expected field to be %s, actual %s (field %s)

Error message

Expected field to be %s, actual %s (field %s)

What it means

GenericHiveRecordCursor.validateType asserts that the Java type requested from a cursor column (e.g. long.class, boolean.class) matches the column's declared type in the Hive schema. Presto's page-building machinery calls getLong/getBoolean/getDouble/getSlice/getObject with the expected type per column; a mismatch means the connector's column-to-type mapping is inconsistent with what the reader actually produces. The raw IllegalArgumentException (not a PrestoException) is deliberate to avoid boxing fieldId in the hot read loop.

Source

Thrown at presto-hive/src/main/java/com/facebook/presto/hive/GenericHiveRecordCursor.java:581

        else if (DATE.equals(type)) {
            parseLongColumn(column);
        }
        else if (TIMESTAMP.equals(type)) {
            parseLongColumn(column);
        }
        else if (type instanceof DecimalType) {
            parseDecimalColumn(column);
        }
        else {
            throw new UnsupportedOperationException("Unsupported column type: " + type);
        }
    }

    private void validateType(int fieldId, Class<?> type)
    {
        if (!types[fieldId].getJavaType().equals(type)) {
            // we don't use Preconditions.checkArgument because it requires boxing fieldId, which affects inner loop performance
            throw new IllegalArgumentException(String.format("Expected field to be %s, actual %s (field %s)", type, types[fieldId], fieldId));
        }
    }

    @Override
    public void close()
    {
        // some hive input formats are broken and bad things can happen if you close them multiple times
        if (closed) {
            return;
        }
        closed = true;

        updateCompletedBytes();

        try {
            recordReader.close();
        }
        catch (IOException e) {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check that each HiveColumnHandle's getColumnType().getJavaType() matches the value type your cursor produces for that field index.
  2. Verify column ordering: the types array passed to GenericHiveRecordCursor must align positionally with the columns list.
  3. If a custom RecordCursorProvider is in use, fix it to construct column handles with types matching the underlying record reader's object inspectors.
  4. If it appeared after a Presto/Hive connector upgrade, review TypeManager/TypeRegistry mapping changes for the affected Hive type.

Example fix

// before
columns.add(new HiveColumnHandle("extra", 1, HIVE_INT, INTEGER, Optional.empty()));
// after (type must match what validateType expects per get call)
columns.add(new HiveColumnHandle("extra", 1, HIVE_INT, BIGINT, Optional.empty())); // if cursor.getLong() is called
Defensive patterns

Strategy: type-guard

Validate before calling

// validate column handle types before building the cursor
for (int i = 0; i < columns.size(); i++) {
    if (!types[i].getJavaType().equals(expectedJavaTypes.get(i))) {
        throw new IllegalStateException("Column " + i + " type mismatch: " + types[i]);
    }
}

Type guard

boolean supportsRead(Class<?> actual, Class<?> requested) {
    return actual != null && actual.equals(requested);
}

Try / catch

try {
    long v = cursor.getLong(field);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Expected field to be")) {
        throw new IllegalStateException("Column handle type mapping is wrong: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling cursor.getLong(field) (or getBoolean/getDouble/getSlice/getObject) on a field whose declared HiveColumnHandle type does not equal types[fieldId].getJavaType() — typically when a custom column handle or type mapping returns the wrong JavaType for that field position.

Common situations: Custom or third-party Hive readers (e.g. custom record cursor providers, ORC/Parquet reader plugins, query engines embedding the Hive connector) that build RecordCursor columns with mismatched type bindings; type registry/mapping changes after a Presto version upgrade; a reader provider that reorders columns without reordering types.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/53520d6ce91253f4. Report an issue: GitHub.