apache/flink · error · InvalidTypesException

The field {} is already contained in the hierarchy of the {}

Error message

The field {} is already contained in the hierarchy of the {}.Please use unique field names through your classes hierarchy

What it means

Thrown by TypeExtractor.getAllDeclaredFields when traversing a class hierarchy and encountering two non-static, non-transient fields with the same name in different levels of the hierarchy (e.g., a field declared in both a class and its superclass). Flink requires unique field names across the entire POJO hierarchy to avoid ambiguity during serialization and field access.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java:2304

     * @param ignoreDuplicates if true, in case of duplicate field names only the lowest one in a
     *     hierarchy will be returned; throws an exception otherwise
     * @return list of fields
     */
    @PublicEvolving
    public static List<Field> getAllDeclaredFields(Class<?> clazz, boolean ignoreDuplicates) {
        List<Field> result = new ArrayList<>();
        while (clazz != null) {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                if (Modifier.isTransient(field.getModifiers())
                        || Modifier.isStatic(field.getModifiers())) {
                    continue; // we have no use for transient or static fields
                }
                if (hasFieldWithSameName(field.getName(), result)) {
                    if (ignoreDuplicates) {
                        continue;
                    } else {
                        throw new InvalidTypesException(
                                "The field "
                                        + field
                                        + " is already contained in the hierarchy of the "
                                        + clazz
                                        + "."
                                        + "Please use unique field names through your classes hierarchy");
                    }
                }
                result.add(field);
            }
            clazz = clazz.getSuperclass();
        }
        return result;
    }

    @PublicEvolving
    public static Field getDeclaredField(Class<?> clazz, String name) {
        for (Field field : getAllDeclaredFields(clazz, true)) {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Rename the field in the subclass or superclass so all field names are unique across the hierarchy.
  2. Remove the duplicate field declaration in the subclass if the parent field is sufficient.
  3. If you cannot change the class hierarchy, consider using getAllDeclaredFields(clazz, true) to ignore duplicates (lowest wins), or annotate with @TypeInfo to provide custom type info.
  4. Mark the duplicate field as transient or static if it should not participate in serialization.

Example fix

// before
class Base {
    private String name;
}
class Child extends Base {
    private String name; // duplicate!
}

// after
class Base {
    private String name;
}
class Child extends Base {
    private String childName; // unique
}
Defensive patterns

Strategy: validation

Validate before calling

// Before type extraction, check for duplicate field names
List<Field> allFields = getAllDeclaredFields(clazz, true); // ignore dups to probe
Set<String> names = new HashSet<>();
for (Field f : allFields) {
    if (!names.add(f.getName())) {
    // duplicate field name detected across hierarchy
    }
}

Type guard

static boolean hasUniqueFieldNames(Class<?> clazz) {
    Set<String> seen = new HashSet<>();
    Class<?> c = clazz;
    while (c != null) {
        for (Field f : c.getDeclaredFields()) {
            if (Modifier.isTransient(f.getModifiers()) || Modifier.isStatic(f.getModifiers())) continue;
            if (!seen.add(f.getName())) return false;
        }
        c = c.getSuperclass();
    }
    return true;
}

Try / catch

try {
    List<Field> fields = getAllDeclaredFields(clazz, false);
} catch (InvalidTypesException e) {
    // fall back: ignore duplicates (lowest in hierarchy wins)
    fields = getAllDeclaredFields(clazz, true);
}

Prevention

When it happens

Trigger: Called during getAllDeclaredFields(clazz, false) when a class hierarchy contains two or more fields with identical names (e.g., a field 'id' in both a subclass and its parent class), and ignoreDuplicates is false. This is triggered during POJO analysis when the type extractor walks the class hierarchy.

Common situations: A POJO subclass that redeclares a field already present in its superclass (field shadowing). Lombok-generated fields that collide with manually declared parent fields. JPA entity hierarchies where @Id fields are redeclared. Using third-party base classes with fields that conflict with your subclass fields.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/9fd46d42a870b073. Report an issue: GitHub.