{"record":{"id":"ef1c3589d30f33fb","repo":"quarkusio/quarkus","slug":"method-already-defined-fullyqualifiedmethodname","errorCode":null,"errorMessage":"Method already defined: ${fullyQualifiedMethodName} in ${fullyQualifiedServiceName}","messagePattern":"Method already defined: (.+?) in (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/grpc/reflection/src/main/java/io/quarkus/grpc/reflection/service/GrpcServerIndex.java","lineNumber":132,"sourceCode":"        for (Descriptors.Descriptor type : fd.getMessageTypes()) {\n            processType(type, fd, descriptorsBySymbol, descriptorsByExtensionAndNumber);\n        }\n        for (Descriptors.FieldDescriptor extension : fd.getExtensions()) {\n            processExtension(extension, fd, descriptorsByExtensionAndNumber);\n        }\n    }\n\n    private void processService(Descriptors.ServiceDescriptor service, FileDescriptor fd,\n            Map<String, FileDescriptor> descriptorsBySymbol) {\n        String fullyQualifiedServiceName = service.getFullName();\n        if (descriptorsBySymbol.containsKey(fullyQualifiedServiceName)) {\n            throw new IllegalStateException(\"Service already defined: \" + fullyQualifiedServiceName);\n        }\n        descriptorsBySymbol.put(fullyQualifiedServiceName, fd);\n        for (Descriptors.MethodDescriptor method : service.getMethods()) {\n            String fullyQualifiedMethodName = method.getFullName();\n            if (descriptorsBySymbol.containsKey(fullyQualifiedMethodName)) {\n                throw new IllegalStateException(\n                        \"Method already defined: \" + fullyQualifiedMethodName + \" in \" + fullyQualifiedServiceName);\n            }\n            descriptorsBySymbol.put(fullyQualifiedMethodName, fd);\n        }\n    }\n\n    private void processType(Descriptors.Descriptor type, FileDescriptor fd,\n            Map<String, FileDescriptor> descriptorsBySymbol,\n            Map<String, Map<Integer, FileDescriptor>> descriptorsByExtensionAndNumber) {\n        String fullyQualifiedTypeName = type.getFullName();\n        if (descriptorsBySymbol.containsKey(fullyQualifiedTypeName)) {\n            throw new IllegalStateException(\"Type already defined: \" + fullyQualifiedTypeName);\n        }\n        descriptorsBySymbol.put(fullyQualifiedTypeName, fd);\n        for (Descriptors.FieldDescriptor extension : type.getExtensions()) {\n            processExtension(extension, fd, descriptorsByExtensionAndNumber);\n        }\n        for (Descriptors.Descriptor nestedType : type.getNestedTypes()) {","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/grpc/reflection/src/main/java/io/quarkus/grpc/reflection/service/GrpcServerIndex.java#L114-L150","documentation":"While indexing reflection metadata, every method's fully qualified name (package.Service.Method) must be unique. processService throws this IllegalStateException when a method full name was already registered in the descriptorsBySymbol map.","triggerScenarios":"Two service definitions contain methods resolving to the same fully qualified method name — normally a symptom of a duplicated service/method declaration across proto files processed earlier.","commonSituations":"Two proto packages generating the same package.Service.Method trio; the same proto compiled into two classpath artifacts; misconfigured proto include paths causing double generation.","solutions":["Ensure unique proto packages so method full names cannot collide.","Remove duplicated proto sources/dependencies (mvn dependency:tree, exclude the extra artifact).","Rename the colliding method in the duplicate proto.","Regenerate stubs after fixing (mvn clean) so stale descriptors don't linger."],"exampleFix":"// before\npackage p; service S { rpc Get (Req) returns (Res); }  // in two files\n// after\n// second file: package p2; service S { rpc Get (Req) returns (Res); }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    startServer();\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"Method already defined:\")) {\n        // the message names method and service; adjust the colliding proto package\n    } else throw e;\n}","preventionTips":["Unique proto packages make method full names unique automatically","Lint protos for duplicate package.Service.Method triples","Exclude duplicated proto dependencies","Clean rebuild after proto changes to avoid stale descriptors"],"tags":["grpc","reflection","protobuf","duplicate-method"],"backgroundTag":"duplicate-proto-symbol","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}