{"record":{"id":"10f22321cfa96e7f","repo":"NationalSecurityAgency/ghidra","slug":"service-receiver-method-may-take-only-one-paramete","errorCode":null,"errorMessage":"Service receiver method may take only one parameter","messagePattern":"Service receiver method may take only one parameter","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/plugintool/util/AutoServiceListener.java","lineNumber":74,"sourceCode":"\t\t\t}\n\t\t}\n\n\t\t@Override\n\t\tpublic Class<S> getServiceIface() {\n\t\t\treturn iface;\n\t\t}\n\t}\n\n\tprotected static class MethodServiceSetter<R, S> implements ServiceSetter<R, S> {\n\t\tprotected final Method method;\n\t\tprotected final Class<S> iface;\n\n\t\t@SuppressWarnings(\"unchecked\")\n\t\tpublic MethodServiceSetter(Method method) {\n\t\t\tthis.method = method;\n\t\t\tClass<?>[] types = method.getParameterTypes();\n\t\t\tif (types.length != 1) {\n\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\"Service receiver method may take only one parameter\");\n\t\t\t}\n\t\t\tthis.iface = (Class<S>) types[0];\n\n\t\t\tmethod.setAccessible(true);\n\t\t}\n\n\t\t@Override\n\t\tpublic void set(R receiver, S service) {\n\t\t\ttry {\n\t\t\t\tmethod.invoke(receiver, service);\n\t\t\t}\n\t\t\tcatch (IllegalAccessException | IllegalArgumentException e) {\n\t\t\t\tthrow new AssertionError(e);\n\t\t\t}\n\t\t\tcatch (InvocationTargetException e) {\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tif (cause instanceof RuntimeException) {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/plugintool/util/AutoServiceListener.java#L56-L92","documentation":"Thrown by AutoServiceListener.MethodServiceSetter when a method annotated @AutoServiceConsumed does not take exactly one parameter. The framework injects a service by invoking the method with the service instance, so the method must declare exactly one parameter whose type is the service interface. Zero, two, or more parameters are rejected at setter-construction time.","triggerScenarios":"An @AutoServiceConsumed method with no parameters, or with two or more. Adding extra parameters (e.g. a context or a flag) beyond the service. A void no-arg method mistakenly annotated as a service consumer.","commonSituations":"Refactoring a service receiver to take additional arguments; annotating an initialization method that takes no args; copy-paste of an annotation onto a method with the wrong shape.","solutions":["Give the @AutoServiceConsumed method exactly one parameter typed as the service interface to receive.","Move extra inputs into receiver fields or obtain them inside the method body.","Remove @AutoServiceConsumed from methods that are not single-service receivers."],"exampleFix":"// before\n@AutoServiceConsumed\npublic void onService(MyService svc, PluginTool tool) { ... } // 2 params\n\n// after\n@AutoServiceConsumed\npublic void onService(MyService svc) {\n  doWith(this.tool, svc);\n}","handlingStrategy":"validation","validationCode":"if (method.getParameterCount() != 1) {\n  throw new IllegalStateException(\n    \"@AutoServiceConsumed method must take exactly one param: \" + method);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give each @AutoServiceConsumed method exactly one parameter.","Obtain extra context from receiver fields, not parameters.","Scan for mis-annotated methods in a wiring unit test."],"tags":["ghidra","service-injection","annotation","arity"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}