{"record":{"id":"35903c67965617ca","repo":"apache/cassandra","slug":"unsupported-injectable-field-type-in-class-onl","errorCode":null,"errorMessage":"Unsupported injectable field type:  in class . Only INodeProbeFactory and Output are supported.","messagePattern":"Unsupported injectable field type:  in class \\. Only INodeProbeFactory and Output are supported\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tools/NodeTool.java","lineNumber":345,"sourceCode":"                {\n                    Field[] fields = beanClass.getDeclaredFields();\n                    for (Field field : fields)\n                    {\n                        if (!field.isAnnotationPresent(Inject.class))\n                            continue;\n                        if (field.getType().equals(INodeProbeFactory.class))\n                        {\n                            field.setAccessible(true);\n                            field.set(bean, nodeProbeFactory);\n                        }\n                        else if (field.getType().equals(Output.class))\n                        {\n                            field.setAccessible(true);\n                            field.set(bean, output);\n                        }\n                        else\n                        {\n                            throw new RuntimeException(\"Unsupported injectable field type: \" + field.getType() +\n                                    \" in class \" + beanClass.getName() + \". \" +\n                                    \"Only INodeProbeFactory and Output are supported.\");\n                        }\n                    }\n                }\n                while ((beanClass = beanClass.getSuperclass()) != null);\n                return bean;\n            }\n            catch (Exception e)\n            {\n                throw new CommandLine.InitializationException(\"Failed to create instance of \" + cls, e);\n            }\n        }\n    }\n}\n","sourceCodeStart":327,"sourceCodeEnd":361,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tools/NodeTool.java#L327-L361","documentation":"NodeTool uses a small dependency-injection mechanism to populate @Inject annotated fields on command classes. Only two injectable types are supported: INodeProbeFactory and Output. Any command declaring an @Inject field of another type triggers this RuntimeException during bean creation.","triggerScenarios":"Declaring an @Inject (NodeTool's injection annotation) field whose declared type is neither INodeProbeFactory nor Output in a NodeTool command (or a superclass of one), then invoking that command — create() iterates fields up the class hierarchy and throws on the first unsupported type.","commonSituations":"Developers writing custom nodetool commands try to inject a probe implementation class, a configuration object, or a service instead of using INodeProbeFactory/Output; refactoring moves an injected field into a parent class so it now gets scanned.","solutions":["Change the field type to INodeProbeFactory (and call create() on it to get a NodeProbe) or Output","Remove the @Inject annotation and obtain the dependency inside the command body instead","If you need a NodeProbe, inject INodeProbeFactory and have the factory construct it"],"exampleFix":"// before\n@Inject\nprivate NodeProbe probe;\n// after\n@Inject\nprivate INodeProbeFactory nodeProbeFactory;\n...\ntry (NodeProbe probe = nodeProbeFactory.create()) { /* use probe */ }","handlingStrategy":"validation","validationCode":"for (Field f : commandClass.getDeclaredFields())\n    if (f.isAnnotationPresent(Inject.class)\n        && !INodeProbeFactory.class.isAssignableFrom(f.getType())\n        && !Output.class.isAssignableFrom(f.getType()))\n        throw new IllegalStateException(\"Unsupported @Inject type: \" + f.getType());","typeGuard":"static boolean isInjectable(Class<?> t) {\n    return INodeProbeFactory.class.isAssignableFrom(t) || Output.class.isAssignableFrom(t);\n}","tryCatchPattern":"try { toolFactory.create(Cmd.class); }\ncatch (RuntimeException e) { LOG.error(\"command wiring failed\", e); }","preventionTips":["Only inject INodeProbeFactory or Output in nodetool commands","Obtain other dependencies inside execute(), not via injection","Re-check inherited fields when moving @Inject fields to superclasses"],"tags":["nodetool","dependency-injection","reflection","cassandra"],"backgroundTag":"unsupported-operation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}