apache/iceberg · error · UnsupportedOperationException

Cannot coerce value to int:

Error message

Cannot coerce value to int: 

What it means

AvroSchemaUtil.toInt converts an Avro property value (typically a field-id stored in the 'field-id' custom property) into an int. It accepts Numbers and numeric Strings; any other object type cannot be coerced and triggers an UnsupportedOperationException naming the offending value.

Source

Thrown at core/src/main/java/org/apache/iceberg/avro/AvroSchemaUtil.java:432

        return mappedField.id();
      }
    }

    return null;
  }

  public static boolean hasFieldId(Schema.Field field) {
    return field.getObjectProp(FIELD_ID_PROP) != null;
  }

  private static int toInt(Object value) {
    if (value instanceof Number) {
      return ((Number) value).intValue();
    } else if (value instanceof String) {
      return Integer.parseInt((String) value);
    }

    throw new UnsupportedOperationException("Cannot coerce value to int: " + value);
  }

  static Schema copyRecord(Schema record, List<Schema.Field> newFields, String newName) {
    Schema copy;
    if (newName != null) {
      copy = Schema.createRecord(newName, record.getDoc(), null, record.isError(), newFields);
      // the namespace is defaulted to the record's namespace if it is null, which causes renames
      // without the namespace to fail. using "" instead of null changes this behavior to match the
      // original schema.
      copy.addAlias(record.getName(), record.getNamespace() == null ? "" : record.getNamespace());
    } else {
      copy =
          Schema.createRecord(
              record.getName(),
              record.getDoc(),
              record.getNamespace(),
              record.isError(),
              newFields);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Fix the writer to emit 'field-id' as a numeric value or numeric string (standard Iceberg Avro type conversion)
  2. Pre-process/repair the Avro schema: set the correct integer field-id before reading
  3. If reading third-party files, remap them with a custom reader instead of relying on Iceberg field IDs
  4. Log and inspect the offending value type to identify the writer that produced it

Example fix

// before: prop written as non-numeric
schema.addProp("field-id", true);
// after: numeric value (or numeric string)
schema.addProp("field-id", 42);
// or as string that parses
schema.addProp("field-id", String.valueOf(42));
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = schema.getObjectProp("field-id");
if (!(v instanceof Number) && !(v instanceof String)) {
  throw new IllegalStateException("Bad field-id property: " + v);
}
if (v instanceof String && !((String) v).chars().allMatch(Character::isDigit)) {
  throw new IllegalStateException("Non-numeric field-id: " + v);
}

Type guard

boolean isCoercibleToInt(Object v) {
  return v instanceof Number || (v instanceof String && ((String) v).matches("-?\\d+"));
}

Try / catch

try {
  int id = AvroSchemaUtil.getId(field);
} catch (UnsupportedOperationException e) {
  LOG.warn("Unreadable field-id on {}", field.fullName());
  id = NO_ID;
}

Prevention

When it happens

Trigger: Reading field IDs from an Avro schema whose 'field-id' property was written as a non-numeric type (Boolean, Map, List) or is missing its numeric value; calling getId/keyId/valueId/elementId/getFieldId on a schema produced by a foreign Avro writer that does not follow Iceberg's field-id convention.

Common situations: Files written by third-party Avro tools that copy Iceberg schema properties incorrectly; hand-edited Avro schemas; schemas round-tripped through systems that re-serialize custom props as JSON objects/booleans.

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/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/c28b190bd7fc70d4. Report an issue: GitHub.