quarkusio/quarkus · error · IllegalArgumentException
${targetType.getName()} has no String constructor
Error message
${targetType.getName()} has no String constructor What it means
TypeConverter.convert() maps a String to a target type by reflection. It requires the target class to expose a public/no-arg-access constructor accepting a single String; if getDeclaredConstructor(String.class) fails, this IllegalArgumentException is thrown. The library uses it for generic String->T conversion (e.g. header/param conversion), so any type without a String constructor simply cannot be converted this way.
Source
Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/util/TypeConverter.java:236
/**
* @param <T> type
* @param source source string
* @param targetType target type
* @return object instance of type T
* @throws IllegalArgumentException if not suitable constructor was found
* @throws InstantiationException if the underlying constructor represents an abstract class
* @throws IllegalAccessException if the underlying constructor is not accessible
* @throws InvocationTargetException if the underlying constructor throws exception
*/
private static <T> T getTypeViaStringConstructor(String source, Class<T> targetType) {
T result = null;
Constructor<T> c = null;
try {
c = targetType.getDeclaredConstructor(String.class);
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException((targetType.getName() + " has no String constructor"), e);
}
try {
result = c.newInstance(source);
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
return result;
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Add a public constructor accepting a single String to the target type
- Add a public static valueOf(String) or fromString(String) factory method if the conversion utility supports it
- Convert manually before calling the converter, or use a different converter supporting the type
- If the type is under your control and should not be string-convertible, stop using TypeConverter for it
Example fix
// before
public class PageParam {
public PageParam(int number) { this.number = number; }
}
// after
public class PageParam {
public PageParam(String value) { this.number = Integer.parseInt(value); }
} Defensive patterns
Strategy: type-guard
Validate before calling
boolean hasStringConstructor(Class<?> t) {
try { t.getDeclaredConstructor(String.class); return true; }
catch (NoSuchMethodException e) { return false; }
}
// call: if (!hasStringConstructor(targetType)) throw new IllegalStateException(targetType + " not string-convertible"); Type guard
static boolean isStringConvertible(Class<?> t) {
if (t.isInterface() || t.isPrimitive()) return false;
try { t.getDeclaredConstructor(String.class); return true; }
catch (NoSuchMethodException e) { return false; }
} Try / catch
try {
T value = converter.getType(targetType, raw);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().endsWith("has no String constructor")) {
value = fallbackConvert(targetType, raw); // custom converter
} else throw e;
} Prevention
- Give every REST parameter/header/cookie type a public String constructor
- Prefer static fromString(String)/valueOf(String) factory conventions (JAX-RS standard)
- Write a startup test that reflects over all custom param types for String constructors
- Avoid raw custom classes in generic conversion utilities
When it happens
Trigger: Calling TypeConverter.getType() (via getTypeViaStringConstructor) with a targetType that has no constructor taking a single String, e.g. converting to a primitive wrapperless custom class, an interface, or a class with only (int) or (OtherType) constructors.
Common situations: Custom header/cookie/path parameter types in JAX-RS that lack a String constructor or static fromString/valueOf method; refactoring a class and removing its String constructor while it is still used as a REST parameter type.
Related errors
- Parameter: ${i} of the constructor of class '${resourceDotNa
- Error loading naming strategy: ${strategy.substringAfter('.
- Date instances are not supported by this class.
- Endpoint return type not supported yet: ${returnType}
- Failed to initialize converters for injected class${i.getInj
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/4fcee175dbc88c87.
Report an issue: GitHub.