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

  1. Add a public constructor accepting a single String to the target type
  2. Add a public static valueOf(String) or fromString(String) factory method if the conversion utility supports it
  3. Convert manually before calling the converter, or use a different converter supporting the type
  4. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/4fcee175dbc88c87. Report an issue: GitHub.