conductor-oss/conductor · error · IllegalArgumentException
duplicate type declaration:
Error message
duplicate type declaration:
What it means
Thrown as IllegalArgumentException by TypeMapper.declare when a Class is already present in the types map. declare() is meant to register each message type exactly once; a second declaration for the same class indicates duplicate processing and is rejected to avoid silently overwriting the first mapping.
Source
Thrown at annotations-processor/src/main/java/com/netflix/conductor/annotationsprocessor/protogen/types/TypeMapper.java:106
for (Map.Entry<Type, AbstractType> pair : types.entrySet()) {
AbstractType t = pair.getValue();
if (t instanceof MessageType) {
if (((Class) t.getJavaType()).getSimpleName().equals(className))
return (MessageType) t;
}
}
return null;
}
public MessageType declare(Class type, MessageType parent) {
return declare(type, (ClassName) parent.getJavaProtoType(), parent.getProtoFilePath());
}
public MessageType declare(Class type, ClassName parentType, String protoFilePath) {
String simpleName = type.getSimpleName();
MessageType t = new MessageType(type, parentType.nestedClass(simpleName), protoFilePath);
if (types.containsKey(type)) {
throw new IllegalArgumentException("duplicate type declaration: " + type);
}
types.put(type, t);
return t;
}
public MessageType baseClass(ClassName className, String protoFilePath) {
return new MessageType(Object.class, className, protoFilePath);
}
}
View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Ensure each @ProtoMessage class is scanned once — deduplicate the source set or jars passed to processPackage.
- Guard declare() with a containsKey check if calling it from custom code, or skip already-known types.
- If the duplicate comes from two jars shipping the same class, exclude one from the protogen source classpath.
Example fix
// before
public MessageType declare(Class type, ClassName parentType, String protoFilePath) {
...
if (types.containsKey(type)) {
throw new IllegalArgumentException("duplicate type declaration: " + type);
}
...
}
// after — tolerate re-declaration of the identical mapping
if (types.containsKey(type)) {
return (MessageType) types.get(type);
} Defensive patterns
Strategy: validation
Validate before calling
public MessageType safeDeclare(Class type, ClassName parentType, String protoFilePath) {
if (types.containsKey(type)) {
return (MessageType) types.get(type); // idempotent re-declare
}
return declare(type, parentType, protoFilePath);
} Prevention
- Make declare() idempotent by returning the existing mapping on repeat calls.
- Deduplicate the source set/jars passed to processPackage.
- Exclude duplicate classes shipped in multiple jars from the protogen classpath.
When it happens
Trigger: processClass/processPackage visits the same @ProtoMessage class twice, or two classes share a simple name path that collides in the types map; manual TypeMapper.declare(SomeClass,...) called twice for the same Class key.
Common situations: A class present in two scanned packages/jars; a build that runs protogen discovery over overlapping source sets; a base class and a subclass both being declared with the same Class object.
Related errors
- cannot map non-scalar map key:
- Cannot map type:
- cannot wrap primitive type:
- missing wrapper class:
- missing Jar file
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/2e605494618e87c2.
Report an issue: GitHub.