{"record":{"id":"2e605494618e87c2","repo":"conductor-oss/conductor","slug":"duplicate-type-declaration","errorCode":null,"errorMessage":"duplicate type declaration: ","messagePattern":"duplicate type declaration: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"annotations-processor/src/main/java/com/netflix/conductor/annotationsprocessor/protogen/types/TypeMapper.java","lineNumber":106,"sourceCode":"        for (Map.Entry<Type, AbstractType> pair : types.entrySet()) {\n            AbstractType t = pair.getValue();\n            if (t instanceof MessageType) {\n                if (((Class) t.getJavaType()).getSimpleName().equals(className))\n                    return (MessageType) t;\n            }\n        }\n        return null;\n    }\n\n    public MessageType declare(Class type, MessageType parent) {\n        return declare(type, (ClassName) parent.getJavaProtoType(), parent.getProtoFilePath());\n    }\n\n    public MessageType declare(Class type, ClassName parentType, String protoFilePath) {\n        String simpleName = type.getSimpleName();\n        MessageType t = new MessageType(type, parentType.nestedClass(simpleName), protoFilePath);\n        if (types.containsKey(type)) {\n            throw new IllegalArgumentException(\"duplicate type declaration: \" + type);\n        }\n        types.put(type, t);\n        return t;\n    }\n\n    public MessageType baseClass(ClassName className, String protoFilePath) {\n        return new MessageType(Object.class, className, protoFilePath);\n    }\n}\n","sourceCodeStart":88,"sourceCodeEnd":116,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/annotations-processor/src/main/java/com/netflix/conductor/annotationsprocessor/protogen/types/TypeMapper.java#L88-L116","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\npublic MessageType declare(Class type, ClassName parentType, String protoFilePath) {\n    ...\n    if (types.containsKey(type)) {\n        throw new IllegalArgumentException(\"duplicate type declaration: \" + type);\n    }\n    ...\n}\n// after — tolerate re-declaration of the identical mapping\nif (types.containsKey(type)) {\n    return (MessageType) types.get(type);\n}","handlingStrategy":"validation","validationCode":"public MessageType safeDeclare(Class type, ClassName parentType, String protoFilePath) {\n    if (types.containsKey(type)) {\n        return (MessageType) types.get(type); // idempotent re-declare\n    }\n    return declare(type, parentType, protoFilePath);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["protogen","protobuf","type-mapping","codegen"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}