prestodb/presto · error · PrestoException

FUNCTION_IMPLEMENTATION_ERROR

FUNCTION_IMPLEMENTATION_ERROR

Error message

Object is not a Block, but 

What it means

Field.cleanObject normalizes user-supplied Java objects into the representation the connector expects. For an ARRAY type, the value must be a Presto Block; passing any other object throws PrestoException FUNCTION_IMPLEMENTATION_ERROR including the actual class found. This signals a programming error in the caller, not a user-input problem.

Source

Thrown at presto-accumulo/src/main/java/com/facebook/presto/accumulo/model/Field.java:392

    /**
     * Does it's damnedest job to convert the given object to the given type.
     *
     * @param value Object to convert
     * @param type Destination Presto type
     * @return Null if null, the converted type of it could convert it, or the same value if it is fine just the way it is :D
     * @throws PrestoException If the given object is not any flavor of the given type
     */
    private static Object cleanObject(Object value, Type type)
    {
        if (value == null) {
            return null;
        }

        // Array? Better be a block!
        if (Types.isArrayType(type)) {
            if (!(value instanceof Block)) {
                throw new PrestoException(FUNCTION_IMPLEMENTATION_ERROR, "Object is not a Block, but " + value.getClass());
            }
            return value;
        }

        // Map? Better be a block!
        if (Types.isMapType(type)) {
            if (!(value instanceof Block)) {
                throw new PrestoException(FUNCTION_IMPLEMENTATION_ERROR, "Object is not a Block, but " + value.getClass());
            }
            return value;
        }

        // And now for the plain types
        if (type.equals(BIGINT)) {
            if (!(value instanceof Long)) {
                throw new PrestoException(FUNCTION_IMPLEMENTATION_ERROR, "Object is not a Long, but " + value.getClass());
            }
        }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Convert the Java collection to a Presto Block before constructing the Field (use a BlockBuilder for the element type and write each element).
  2. If you already hold a Block, pass it directly — do not re-wrap it.
  3. Inspect the exception message: it names the actual class (e.g., java.util.ArrayList) so you can find where the wrong object is created.
  4. If migrating from an older connector version that used List, update the code to the Block-based API.

Example fix

// before: passing a Java list for an array field
Field f = new Field(arrayType, Arrays.asList(1L, 2L));
// after: build a Block
BlockBuilder bb = BIGINT.createBlockBuilder(null, 2);
BIGINT.writeLong(bb, 1L);
BIGINT.writeLong(bb, 2L);
Field f = new Field(arrayType, bb.build());
Defensive patterns

Strategy: type-guard

Validate before calling

// before constructing the Field
if (Types.isArrayType(type) && !(value instanceof Block)) {
    value = toArrayBlock((List<?>) value, elementType);
}

Type guard

boolean isValidArrayValue(Type type, Object value) {
    return !Types.isArrayType(type) || value instanceof Block;
}

Prevention

When it happens

Trigger: Constructing a Field with an ARRAY type while passing a value that is not a Presto Block — e.g., a java.util.List, Object[], or Iterator instead of the Block produced by the Presto block machinery.

Common situations: Custom connector code or tests building array fields from Java collections instead of Blocks; a conversion layer that forgot to call the block builder; upgrade where the internal representation changed from List to Block.

Related errors


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