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

  1. Ensure each @ProtoMessage class is scanned once — deduplicate the source set or jars passed to processPackage.
  2. Guard declare() with a containsKey check if calling it from custom code, or skip already-known types.
  3. 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

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


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/2e605494618e87c2. Report an issue: GitHub.