prestodb/presto · error · IllegalArgumentException

Unsupported FieldVector type: {fieldVector.getClass()}

Error message

Unsupported FieldVector type: {fieldVector.getClass()}

What it means

ArrowBlockBuilder.buildDictionaryBlock encounters a FieldVector whose Arrow type it cannot convert to a Presto DictionaryBlock. The builder dispatches on known Arrow vector classes (Bit, Int, BigInt, VarChar, etc.) and throws IllegalArgumentException with the vector's Java class when no branch matches. It signals an Arrow column type this connector does not map to any Presto type.

Source

Thrown at presto-common-arrow/src/main/java/com/facebook/plugin/arrow/ArrowBlockBuilder.java:227

            SmallIntVector smallIntIndicesVector = (SmallIntVector) fieldVector;
            int[] ids = new int[smallIntIndicesVector.getValueCount()];
            for (int i = 0; i < smallIntIndicesVector.getValueCount(); i++) {
                ids[i] = smallIntIndicesVector.get(i);
            }
            return new DictionaryBlock(ids.length, dictionaryblock, ids);
        }
        else if (fieldVector instanceof TinyIntVector) {
            // Get the TinyInt indices vector
            TinyIntVector tinyIntIndicesVector = (TinyIntVector) fieldVector;
            int[] ids = new int[tinyIntIndicesVector.getValueCount()];
            for (int i = 0; i < tinyIntIndicesVector.getValueCount(); i++) {
                ids[i] = tinyIntIndicesVector.get(i);
            }
            return new DictionaryBlock(ids.length, dictionaryblock, ids);
        }
        else {
            // Handle the case where the FieldVector is of an unsupported type
            throw new IllegalArgumentException("Unsupported FieldVector type: " + fieldVector.getClass());
        }
    }

    private void assignBlockFromValueVector(ValueVector vector, Type type, BlockBuilder builder, int startIndex, int endIndex)
    {
        if (vector instanceof BitVector) {
            assignBlockFromBitVector((BitVector) vector, type, builder, startIndex, endIndex);
        }
        else if (vector instanceof TinyIntVector) {
            assignBlockFromTinyIntVector((TinyIntVector) vector, type, builder, startIndex, endIndex);
        }
        else if (vector instanceof IntVector) {
            assignBlockFromIntVector((IntVector) vector, type, builder, startIndex, endIndex);
        }
        else if (vector instanceof SmallIntVector) {
            assignBlockFromSmallIntVector((SmallIntVector) vector, type, builder, startIndex, endIndex);
        }
        else if (vector instanceof BigIntVector) {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check the thrown class name and confirm whether a mapping exists for that Arrow type in ArrowBlockBuilder
  2. Convert/omit the unmapped column before it reaches the connector, or cast it to a supported Arrow type on the producer side
  3. Add an instanceof branch plus an assignBlockFrom* method for the new vector type in ArrowBlockBuilder
  4. Upgrade the connector/Arrow plugin version that may already support the vector type

Example fix

// before: unmapped TimeMicroVector falls through to the throw
// after: add a branch before the else
if (fieldVector instanceof TimeMicroVector) {
    return buildTimestampBlock((TimeMicroVector) fieldVector, type);
}
Defensive patterns

Strategy: type-guard

Validate before calling

// before calling the connector's block building
if (!(fieldVector instanceof BitVector || fieldVector instanceof IntVector
        || fieldVector instanceof BigIntVector || fieldVector instanceof VarCharVector
        || fieldVector instanceof DecimalVector || fieldVector instanceof ListVector
        || fieldVector instanceof StructVector || fieldVector instanceof MapVector)) {
    throw new IllegalStateException("Unmapped Arrow vector type: " + fieldVector.getClass().getName());
}

Type guard

boolean isSupportedArrowVector(ValueVector v) {
    return v instanceof BitVector || v instanceof TinyIntVector || v instanceof IntVector
        || v instanceof BigIntVector || v instanceof Float4Vector || v instanceof Float8Vector
        || v instanceof DecimalVector || v instanceof VarCharVector || v instanceof DateDayVector
        || v instanceof DateMilliVector || v instanceof TimeSecVector || v instanceof TimeMilliVector
        || v instanceof TimeStampMicroVector || v instanceof TimeStampMilliVector
        || v instanceof ListVector || v instanceof FixedSizeListVector
        || v instanceof StructVector || v instanceof MapVector;
}

Try / catch

try {
    Block block = blockBuilder.buildBlockFromFieldVector(fieldVector, type);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Unsupported FieldVector type")) {
        LOG.warn("Skipping unmapped Arrow column: %s (%s)", fieldVector.getName(), fieldVector.getClass());
        return null; // or fall back to a VARCHAR-serialized block
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling buildBlockFromFieldVector with a FieldVector whose concrete class (e.g. TimeMicroVector, DurationVector, Interval vector, or a newer Arrow vector type) has no instanceof branch in buildDictionaryBlock, so control reaches the final else.

Common situations: Reading Arrow/Flight data produced by a newer Arrow writer with vector types the connector predates; schema drift upstream adds a column of an unmapped type; using an Arrow extension type that materializes as an unhandled vector class.

Related errors


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