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

  1. Exclude void.class from any loop that feeds types into PrimitiveConverter.convert() — it is primitive but unsupported.
  2. Guard with an explicit check: if (primitiveClass == void.class) skip or handle separately.
  3. Use Convert.convert() (the high-level facade) instead of calling PrimitiveConverter.convert() directly, so the registry routes correctly.
  4. 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

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


AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14). Data as JSON: /api/errors/3377a53a99bc20cc. Report an issue: GitHub.