{"record":{"id":"27c3f6adf5eadbbe","repo":"apache/maven","slug":"unable-to-lookup-mojo","errorCode":null,"errorMessage":"Unable to lookup Mojo","messagePattern":"Unable to lookup Mojo","errorType":"exception","errorClass":"PluginContainerException","httpStatus":null,"severity":"error","filePath":"impl/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java","lineNumber":576,"sourceCode":"                LoggerFactory.getLogger(mojoExecution.getMojoDescriptor().getFullGoalName()));\n        try {\n            Injector injector = Injector.create();\n            injector.discover(pluginRealm);\n            // Add known classes\n            // TODO: get those from the existing plexus scopes ?\n            injector.bindInstance(Session.class, sessionV4);\n            injector.bindInstance(Project.class, project);\n            injector.bindInstance(org.apache.maven.api.MojoExecution.class, execution);\n            injector.bindInstance(org.apache.maven.api.plugin.Log.class, log);\n\n            Map<Class<? extends Service>, Supplier<? extends Service>> services = sessionV4.getAllServices();\n            services.forEach((itf, svc) -> injector.bindSupplier((Class<Service>) itf, (Supplier<Service>) svc));\n\n            mojo = mojoInterface.cast(injector.getInstance(\n                    Key.of(mojoDescriptor.getImplementationClass(), mojoDescriptor.getRoleHint())));\n\n        } catch (Exception e) {\n            throw new PluginContainerException(mojoDescriptor, pluginRealm, \"Unable to lookup Mojo\", e);\n        }\n\n        XmlNode dom = mojoExecution.getConfiguration() != null\n                ? mojoExecution.getConfiguration().getDom()\n                : null;\n\n        PlexusConfiguration pomConfiguration;\n\n        if (dom == null) {\n            pomConfiguration = new DefaultPlexusConfiguration(\"configuration\");\n        } else {\n            pomConfiguration = XmlPlexusConfiguration.toPlexusConfiguration(dom);\n        }\n\n        ExpressionEvaluator expressionEvaluator =\n                new PluginParameterExpressionEvaluatorV4(sessionV4, project, execution);\n\n        for (MavenPluginConfigurationValidator validator : configurationValidators) {","sourceCodeStart":558,"sourceCodeEnd":594,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java#L558-L594","documentation":"While loading a Maven-4-style mojo, the Sisu injector's getInstance call on the implementation class (keyed with the descriptor's role hint) threw: the mojo class could not be instantiated - constructor failure, missing binding for an injected parameter, or a hint/annotation mismatch. Any such failure is wrapped in PluginContainerException 'Unable to lookup Mojo'.","triggerScenarios":"The mojo constructor or a field initializer throws; the @Named value on the mojo no longer matches the role hint recorded in plugin.xml; a required injected service has no binding in the realm; the descriptor names an abstract class as implementation.","commonSituations":"Plugin rebuilt without regenerating plugin.xml after renames; descriptors and annotations produced by mismatched maven-plugin-plugin versions; environments missing a service the mojo expects.","solutions":["Unwrap the cause chain - the nested exception is the real reason (missing binding, constructor exception, hint mismatch).","If the hint mismatched, clean-rebuild the plugin so plugin.xml and @Named agree.","Ensure the mojo class is concrete with an injectable constructor (no-arg or @Inject).","Check that every service injected into the mojo is provided by the realm or by Maven core."],"exampleFix":"// before: plugin.xml role hint is \"my-goal\" but the class says\n@Named(\"myMojo\")\nclass MyMojo extends AbstractMojo {}\n// after: names agree (and rebuild so the descriptor matches)\n@Named(\"my-goal\")\nclass MyMojo extends AbstractMojo {}","handlingStrategy":"validation","validationCode":"// run inside the plugin's test suite: fail fast when the mojo cannot be wired\n@Test void mojoIsInstantiable() {\n    Injector i = Guice.createInjector(\n        new WireModule(new ClassSpaceModule(new URLClassSpace(getClass().getClassLoader()))));\n    MyMojo mojo = i.getInstance(Key.of(MyMojo.class, \"my-goal\"));\n    assertNotNull(mojo);\n}","typeGuard":null,"tryCatchPattern":"try {\n    mojo = pluginManager.getConfiguredMojo(mojoInterface, session, mojoExecution);\n} catch (PluginContainerException e) {\n    Throwable root = e;\n    while (root.getCause() != null) root = root.getCause();\n    // root is the real instantiation failure (binding/constructor/hint): fix the plugin, not the POM\n    throw new IllegalStateException(\"mojo wiring failed: \" + root, e);\n}","preventionTips":["Keep maven-plugin-plugin and maven-plugin-annotations versions aligned","Avoid logic in mojo constructors; initialize inside execute()","Run injector smoke tests in plugin CI so lookup failures never reach users"],"tags":["maven","mojo","sisu","guice","lookup"],"backgroundTag":"mojo-instantiation-failure","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}