{"record":{"id":"7c61017f71a44cd1","repo":"quarkusio/quarkus","slug":"multiple-extensions-found-for-keyword-no-message","errorCode":null,"errorMessage":"Multiple extensions found for keyword (no message; handled and reported as \"Multiple extensions matching '${keyword}'\" with the extension list)","messagePattern":"Multiple extensions found for keyword \\(no message; handled and reported as \"Multiple extensions matching '(.+?)'\" with the extension list\\)","errorType":"exception","errorClass":"MultipleExtensionsFoundException","httpStatus":null,"severity":"warning","filePath":"independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/AddExtensionsCommandHandler.java","lineNumber":154,"sourceCode":"                for (Extension e : invocation.getExtensionsCatalog().getExtensions()) {\n                    if (e.getArtifact().getKey().equals(artifactKey)) {\n                        listed = List.of(e);\n                        break;\n                    }\n                }\n\n                //builder.addManagedExtension(new ArtifactCoords(artifactKey, null));\n            } else {\n                listed = listInternalExtensions(quarkusCore, keyword, catalog.getExtensions());\n            }\n            if (listed.isEmpty()) {\n                // No extension found for this keyword.\n                builder.addUnmatchedKeyword(keyword);\n            }\n            // If it's a pattern allow multiple results\n            // See https://github.com/quarkusio/quarkus/issues/11086#issuecomment-666360783\n            else if (listed.size() > 1 && !ExtensionPredicate.isPattern(keyword)) {\n                throw new MultipleExtensionsFoundException(keyword, listed);\n            }\n            for (Extension e : listed) {\n                final ArtifactCoords extensionCoords = e.getArtifact();\n                boolean managed = false;\n                ExtensionOrigin firstPlatform = null;\n                ExtensionOrigin preferredOrigin = null;\n                for (ExtensionOrigin origin : e.getOrigins()) {\n                    if (!origin.isPlatform()) {\n                        continue;\n                    }\n                    if (importedPlatforms.contains(origin.getBom())) {\n                        managed = true;\n                        builder.addManagedExtension(extensionCoords);\n                        break;\n                    }\n                    if (preferredOrigin == null) {\n                        if (preferredBoms.contains(origin.getBom())) {\n                            preferredOrigin = origin;","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/AddExtensionsCommandHandler.java#L136-L172","documentation":"planInstallation throws MultipleExtensionsFoundException when a keyword matches more than one catalog extension and the keyword is not a wildcard pattern. It is handled upstream: the handler reports 'Multiple extensions matching <keyword>' with the candidate list instead of failing hard.","triggerScenarios":"Calling planInstallation (or extensionInstallPlan) with a keyword like 'rest' that matches several extensions (e.g. rest, rest-jackson, resteasy) and is not a '*' pattern.","commonSituations":"Typing a short or generic extension name in 'quarkus add extension'; scripts relying on partial names after a Quarkus version renamed/split extensions (e.g. resteasy-reactive -> quarkus-rest).","solutions":["Use the exact extension name or full GAV (groupId:artifactId)","Use a wildcard pattern (e.g. quarkus-rest*) if multiple matches are intended","Run the list command to inspect matching extensions before adding","Update scripts to the new canonical names after upgrading Quarkus"],"exampleFix":"// before\ninvocation.extensions().add(\"rest\");\n// after\ninvocation.extensions().add(\"quarkus-rest-jackson\");","handlingStrategy":"validation","validationCode":"List<String> matches = catalog.getExtensions().stream()\n    .map(Extension::getArtifact).map(ArtifactCoords::getArtifactId)\n    .filter(id -> id.contains(keyword)).toList();\nif (matches.size() > 1 && !keyword.contains(\"*\")) throw new IllegalArgumentException(\"Ambiguous keyword '\" + keyword + \"': \" + matches);","typeGuard":"static boolean isUnambiguous(String keyword, List<String> ids) {\n    return ids.stream().filter(id -> id.contains(keyword)).count() <= 1 || ExtensionPredicate.isPattern(keyword);\n}","tryCatchPattern":"try { plan = handler.planInstallation(invocation, keywords); } catch (MultipleExtensionsFoundException e) { System.out.println(\"Pick one of: \" + e.getListedExtensions()); }","preventionTips":["Always use full artifact ids or GAVs in scripts","Check extension names after Quarkus upgrades (renames/splits)","Use wildcard patterns intentionally, not by accident","Preview matches with the list command before adding"],"tags":["extensions","ambiguity","cli"],"backgroundTag":"ambiguous-extension-keyword","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}