apache/flink · error · InvalidTypesException
The given class is no subclass of {}
Error message
The given class is no subclass of {} What it means
Thrown by ValueTypeInfo.getValueTypeInfo when the provided class is not a valid subclass of org.apache.flink.types.Value — either it does not extend Value at all, or it is the raw Value.class interface itself (which has no concrete serialization behavior).
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/ValueTypeInfo.java:273
@Override
public boolean canEqual(Object obj) {
return obj instanceof ValueTypeInfo;
}
@Override
public String toString() {
return "ValueType<" + type.getSimpleName() + ">";
}
// --------------------------------------------------------------------------------------------
@PublicEvolving
static <X extends Value> TypeInformation<X> getValueTypeInfo(Class<X> typeClass) {
if (Value.class.isAssignableFrom(typeClass) && !typeClass.equals(Value.class)) {
return new ValueTypeInfo<X>(typeClass);
} else {
throw new InvalidTypesException(
"The given class is no subclass of " + Value.class.getName());
}
}
}
View on GitHub (pinned to 2f3c205e92)
Solutions
- Use a concrete Value subclass (e.g., IntValue, StringValue, or a custom class implementing Value) instead of Value.class itself.
- If the type is not a Value, use the appropriate TypeInformation (e.g., BasicTypeInfo for primitives, PojoTypeInfo for POJOs).
- Ensure generic code that constructs ValueTypeInfo resolves to a concrete Value subclass, not the raw Value interface.
- Register a custom TypeInfoFactory via @TypeInfo if you need custom type info for non-Value types.
Example fix
// before
TypeInformation<?> info = ValueTypeInfo.getValueTypeInfo(Value.class);
// throws: Value.class is not a valid subclass of itself
// after
TypeInformation<?> info = ValueTypeInfo.getValueTypeInfo(MyCustomValue.class);
// where MyCustomValue extends Value implements Value { ... } Defensive patterns
Strategy: validation
Validate before calling
// Check if the class is a valid concrete Value subclass
if (!Value.class.isAssignableFrom(typeClass) || typeClass.equals(Value.class)) {
// not a valid Value subclass; use appropriate TypeInformation
} Type guard
static boolean isValidValueSubclass(Class<?> typeClass) {
return Value.class.isAssignableFrom(typeClass) && !typeClass.equals(Value.class);
} Try / catch
try {
TypeInformation<?> ti = ValueTypeInfo.getValueTypeInfo(typeClass);
} catch (InvalidTypesException e) {
// use a concrete Value subclass or appropriate TypeInformation
ti = TypeInformation.of(typeClass);
} Prevention
- Use concrete Value subclasses (IntValue, StringValue, etc.), never Value.class itself.
- Ensure generic code resolves type parameters to concrete Value implementations.
- If the type is not a Value, use the appropriate TypeInformation class.
When it happens
Trigger: Called when ValueTypeInfo.getValueTypeInfo(typeClass) is invoked with a class that is either not assignable to Value, or is exactly Value.class. This is used internally during type extraction to validate that a class is a concrete Value implementation before constructing a ValueTypeInfo.
Common situations: Passing a raw class that doesn't implement Value to a type extraction context expecting a Value type. Accidentally using Value.class as a type parameter instead of a concrete subclass like IntValue.class. Generic code that resolves the type parameter to Value.class itself rather than a concrete subclass.
Related errors
- Value type expected.
- Type at position {} is not a basic or value type.
- Input mismatch: {}
- Basic type expected.
- Basic type '{}' expected but was '{}'.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/016fa40b5df83c8a.
Report an issue: GitHub.