apache/seatunnel · error · IllegalArgumentException

Cannot convert to boolean:

Error message

Cannot convert to boolean: 

What it means

Iceberg RowConverter throws this when a boolean column value is neither Boolean nor String. Only those two input types are supported by convertBoolean; anything else (e.g. Integer 0/1) is rejected. This protects against silently coercing arbitrary types to booleans.

Source

Thrown at seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/data/RowConverter.java:346

            } else {
                bigDecimal = BigDecimal.valueOf(dbl);
            }
        } else if (value instanceof String) {
            bigDecimal = new BigDecimal((String) value);
        } else {
            throw new IllegalArgumentException(
                    "Cannot convert to BigDecimal: " + value.getClass().getName());
        }
        return bigDecimal.setScale(type.scale(), RoundingMode.HALF_UP);
    }

    protected boolean convertBoolean(Object value) {
        if (value instanceof Boolean) {
            return (boolean) value;
        } else if (value instanceof String) {
            return Boolean.parseBoolean((String) value);
        }
        throw new IllegalArgumentException(
                "Cannot convert to boolean: " + value.getClass().getName());
    }

    protected String convertString(Object value) {
        try {
            if (value instanceof String) {
                return (String) value;
            } else if (value instanceof Number || value instanceof Boolean) {
                return value.toString();
            } else if (value instanceof Map || value instanceof List) {
                return MAPPER.writeValueAsString(value);
            } else {
                return MAPPER.writeValueAsString(value);
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Cast the column upstream (SELECT col::boolean or transform CAST) so the sink receives Boolean/String.
  2. Use a transform to map 0/1 to true/false before the Iceberg sink.
  3. Fix the source connector's type mapping so logical boolean types map to SeaTunnel BooleanType.

Example fix

// before
writer.write(fieldIndex, 1); // Integer for boolean
// after
writer.write(fieldIndex, true); // Boolean accepted by convertBoolean
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(v instanceof Boolean) && !(v instanceof String)) throw new IllegalArgumentException("boolean column must be Boolean/String, got " + (v == null ? "null" : v.getClass().getName()));

Type guard

boolean isBooleanConvertible(Object v) { return v instanceof Boolean || v instanceof String; }

Try / catch

try { sink.write(row); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Cannot convert to boolean")) { /* coerce 0/1 or DLQ */ } else throw e; }

Prevention

When it happens

Trigger: convertBoolean receives e.g. an Integer, Short, or BigDecimal while converting a row field mapped to an Iceberg BOOLEAN column.

Common situations: Sources/databases that encode booleans as numeric 0/1 (MySQL tinyint(1), Oracle NUMBER) pass Integer values to the sink; CDC formats deliver booleans as ints.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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