quarkusio/quarkus · error · IllegalArgumentException
Converter ${converter.name()} must be parameterized with a s
Error message
Converter ${converter.name()} must be parameterized with a single type What it means
A Converter<T> implementation must be parameterized with exactly one type argument. When the parameterized Converter interface found on the converter class has zero or more than one type argument, getConverterType throws this IllegalArgumentException.
Source
Thrown at core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java:1242
return classLoader.loadClass(name);
} catch (ClassNotFoundException e) {
throw new IllegalStateException("The class (" + name + ") cannot be created during deployment.", e);
}
}
private static Type getConverterType(final ClassInfo converter, final CombinedIndexBuildItem combinedIndex) {
if (converter.name().toString().equals(Object.class.getName())) {
throw new IllegalArgumentException(
"Can not add converter " + converter.name() + " that is not parameterized with a type");
}
for (Type type : converter.interfaceTypes()) {
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = type.asParameterizedType();
if (parameterizedType.name().equals(CONVERTER_NAME)) {
List<Type> arguments = parameterizedType.arguments();
if (arguments.size() != 1) {
throw new IllegalArgumentException(
"Converter " + converter.name() + " must be parameterized with a single type");
}
return arguments.get(0);
}
}
}
return getConverterType(combinedIndex.getComputingIndex().getClassByName(converter.superName()), combinedIndex);
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Ensure the class implements io.smallrye.config.Converter<T> with exactly one type parameter
- Verify the imported Converter is io.smallrye.config.Converter, not a same-named interface from another library
- Split any two-type converter into a single-type converter plus an adapter
Example fix
// before
public class PairConverter implements Converter<Pair, String> { ... }
// after
public class PairConverter implements Converter<Pair> { ... } Defensive patterns
Strategy: type-guard
Validate before calling
ParameterizedType pt = (ParameterizedType) ColorConverter.class.getGenericInterfaces()[0];
if (pt.getActualTypeArguments().length != 1) {
throw new IllegalStateException("Converter must have exactly one type argument");
} Type guard
static boolean hasSingleTypeArg(Class<?> c) {
return java.util.Arrays.stream(c.getGenericInterfaces())
.filter(t -> t instanceof ParameterizedType pt
&& pt.getRawType().equals(io.smallrye.config.Converter.class))
.allMatch(t -> ((ParameterizedType) t).getActualTypeArguments().length == 1);
} Prevention
- Import io.smallrye.config.Converter specifically (watch for same-named interfaces)
- Keep converter signatures to a single type parameter; wrap multi-type logic in a holder class
- Add a compile-time annotation processor or test asserting generic arity
- Review converter signatures during code review after copy-paste
When it happens
Trigger: A converter class implements a parameterized type whose raw name equals Converter but whose type-argument list size != 1, discovered while scanning interfaceTypes in config generation.
Common situations: Mistakenly implementing a multi-parameter generic interface variant or copying a generic converter signature like Converter<A, B>; accidentally matching a different Converter interface name with two parameters; IDE auto-import of the wrong Converter type.
Related errors
- Can not add converter ${converter.name()} that is not parame
- A generic type is not allowed here; try creating a subclass
- Unsupported wildcard type: ${wildcard}
- The class (${name}) cannot be created during deployment.
- The supplied 'main-class' value of '${mainClassName}' does n
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/463a530007478635.
Report an issue: GitHub.