apache/seatunnel · error · java.lang.IllegalArgumentException

Unsupported ArrowType: ${arrowType.getClass().getName()}

Error message

Unsupported ArrowType: ${arrowType.getClass().getName()}

What it means

TypeWriterFactory.getWriter looks up a TypeWriter by the ArrowType implementation class in a static registry (Int, FloatingPoint, Utf8, Binary, Bool, Date, Time, TimeStamp, Map, etc.). If the resolved field's ArrowType class has no registered writer, this IllegalArgumentException is thrown. It signals the Lance connector does not support that Arrow type in the sink write path.

Source

Thrown at seatunnel-connectors-v2/connector-lance/src/main/java/org/apache/seatunnel/connectors/seatunnel/lance/sink/writers/TypeWriterFactory.java:44

    private static final Map<Class<? extends ArrowType>, TypeWriter> WRITERS = new HashMap<>();

    static {
        WRITERS.put(ArrowType.Int.class, new IntTypeWriter());
        WRITERS.put(ArrowType.FloatingPoint.class, new FloatingPointTypeWriter());
        WRITERS.put(ArrowType.Bool.class, new BoolTypeWriter());
        WRITERS.put(ArrowType.Utf8.class, new Utf8TypeWriter());
        WRITERS.put(ArrowType.Binary.class, new BinaryTypeWriter());
        WRITERS.put(ArrowType.Decimal.class, new DecimalTypeWriter());
        WRITERS.put(ArrowType.Date.class, new DateTypeWriter());
        WRITERS.put(ArrowType.Timestamp.class, new TimestampTypeWriter());
        WRITERS.put(ArrowType.List.class, new ListTypeWriter());
        WRITERS.put(ArrowType.Map.class, new MapTypeWriter());
    }

    public static TypeWriter getWriter(ArrowType arrowType) {
        TypeWriter writer = WRITERS.get(arrowType.getClass());
        if (writer == null) {
            throw new IllegalArgumentException(
                    "Unsupported ArrowType: " + arrowType.getClass().getName());
        }
        return writer;
    }
}

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Identify the unsupported Arrow type from the exception message and cast the column to a supported type (string, int, double, bool, date, timestamp) in the pipeline.
  2. For decimals, cast to DOUBLE or scale to a string before writing to Lance.
  3. Register a TypeWriter for the missing ArrowType class in TypeWriterFactory's static map if you maintain a fork.
  4. Check the Lance connector docs/source for the supported type matrix and align your schema with it.

Example fix

// before
columns = "price decimal(38,10)"  // -> Arrow Decimal, no writer

// after
columns = "price double"  // or cast decimal to double upstream
Defensive patterns

Strategy: validation

Validate before calling

// Java: verify every field type has a registered writer before writing
for (Field f : schema.getFields()) {
    try {
        TypeWriterFactory.getWriter(f.getType());
    } catch (IllegalArgumentException e) {
        throw new IllegalArgumentException("Column '" + f.getName() + "' uses unsupported type " + f.getType());
    }
}

Type guard

boolean hasWriter(ArrowType t) {
    try { TypeWriterFactory.getWriter(t); return true; }
    catch (IllegalArgumentException e) { return false; }
}

Try / catch

try {
    TypeWriter w = TypeWriterFactory.getWriter(arrowType);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Unsupported ArrowType")) {
        throw new IllegalArgumentException("Cast column to a supported type (string/int/double/bool/date/timestamp): " + e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: A column's SeaTunnel type translates to an ArrowType with no registry entry — e.g. Decimal, DenseUnion, Union, Duration, Interval, or FixedSizeBinary — and FragmentConverter calls TypeWriterFactory.getWriter(field.getType()).

Common situations: DECIMAL/NUMERIC columns from databases (Arrow Decimal type); union or interval types from Flink/Spark sources; new SeaTunnel types added without corresponding Lance connector support.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/16493999457a1b83. Report an issue: GitHub.