chinabugotech/hutool · error · ConvertException
Unsupported target type: {}
Error message
Unsupported target type: {} What it means
Thrown at the end of the static PrimitiveConverter.convert() method when primitiveClass does not match any of the eight supported primitive types (byte, short, int, long, float, double, char, boolean). In normal usage this is nearly unreachable because the constructor pre-validates isPrimitive(), but it can fire if the static convert() method is called directly with an unsupported primitive type such as void.class.
Source
Thrown at hutool-core/src/main/java/cn/hutool/core/convert/impl/PrimitiveConverter.java:90
if (byte.class == primitiveClass) {
return ObjectUtil.defaultIfNull(NumberConverter.convert(value, Byte.class, toStringFunc), 0);
} else if (short.class == primitiveClass) {
return ObjectUtil.defaultIfNull(NumberConverter.convert(value, Short.class, toStringFunc), 0);
} else if (int.class == primitiveClass) {
return ObjectUtil.defaultIfNull(NumberConverter.convert(value, Integer.class, toStringFunc), 0);
} else if (long.class == primitiveClass) {
return ObjectUtil.defaultIfNull(NumberConverter.convert(value, Long.class, toStringFunc), 0);
} else if (float.class == primitiveClass) {
return ObjectUtil.defaultIfNull(NumberConverter.convert(value, Float.class, toStringFunc), 0);
} else if (double.class == primitiveClass) {
return ObjectUtil.defaultIfNull(NumberConverter.convert(value, Double.class, toStringFunc), 0);
} else if (char.class == primitiveClass) {
return Convert.convert(Character.class, value);
} else if (boolean.class == primitiveClass) {
return Convert.convert(Boolean.class, value);
}
throw new ConvertException("Unsupported target type: {}", primitiveClass);
}
}
View on GitHub (pinned to 8870454b2a)
Solutions
- Exclude void.class from any loop that feeds types into PrimitiveConverter.convert() — it is primitive but unsupported.
- Guard with an explicit check: if (primitiveClass == void.class) skip or handle separately.
- Use Convert.convert() (the high-level facade) instead of calling PrimitiveConverter.convert() directly, so the registry routes correctly.
- If subclassing, ensure the constructor's isPrimitive() validation is preserved.
Example fix
// before
PrimitiveConverter.convert(value, void.class, Object::toString); // throws
// after
if (primitiveClass != void.class) {
PrimitiveConverter.convert(value, primitiveClass, Object::toString);
} Defensive patterns
Strategy: validation
Validate before calling
if (primitiveClass == void.class) {
return null; // or throw with a meaningful message
}
PrimitiveConverter.convert(value, primitiveClass, Object::toString); Type guard
static boolean isConvertiblePrimitive(Class<?> clazz) {
return clazz == byte.class || clazz == short.class || clazz == int.class
|| clazz == long.class || clazz == float.class || clazz == double.class
|| clazz == char.class || clazz == boolean.class;
} Try / catch
try {
return PrimitiveConverter.convert(value, primitiveClass, toStringFunc);
} catch (ConvertException e) {
// handle unsupported primitive type (e.g., void.class)
return defaultValue;
} Prevention
- Never pass void.class to PrimitiveConverter.convert().
- Prefer using the constructor-validated instance path over calling the static convert() directly.
- Filter void.class out of any reflective type iteration before conversion.
When it happens
Trigger: Calling PrimitiveConverter.convert(value, void.class, toStringFunc) directly. Subclassing PrimitiveConverter and bypassing the constructor check, then reaching convertInternal with a targetType like void.class. The Java primitive void.class is technically primitive but has no conversion path here.
Common situations: Reflective code that enumerates all primitive types and attempts conversion for each, including void.class. Unit tests that exercise the converter with the full Primitive enum. Framework code that derives primitiveClass from a Method return type that happens to be void.
Related errors
- [{}] is not a primitive class!
- Unsupported source type: [{}] to [{}]
- Unsupported type: [{}] from map: [{}]
- [type] and [defaultValue] are both null for Converter [{}],
- Default value [{}]({}) is not the instance of [{}]
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/3377a53a99bc20cc.
Report an issue: GitHub.