{"record":{"id":"8e56e6df658f1255","repo":"quarkusio/quarkus","slug":"at-least-one-package-name-must-be-specified","errorCode":null,"errorMessage":"At least one package name must be specified","messagePattern":"At least one package name must be specified","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/deployment/src/main/java/io/quarkus/deployment/builditem/ModuleOpenBuildItem.java","lineNumber":62,"sourceCode":"     * Create a new ModuleOpenBuildItem instance.\n     * We are currently imposing a strict expectation to not refer to the unnamed module\n     * as an opening module so to encourage extension maintainers to pick the right module name\n     * in preparation for more extensive modularization.\n     * If the library to which you're opening to isn't on the module path yet at this point, it\n     * should still be beneficial to refer to it by the expected module name.\n     * When a module name is specified which couldn't be identified by name, we'll fallback\n     * the opening module name to the unnamed module to allow for an easier transition.\n     *\n     * @param openedModuleName The name of the module which needs to be opened.\n     * @param openingModuleName The name of the module which is being granted access.\n     * @param packageNames The packages which are being opened. At least one must be specified.\n     */\n    public ModuleOpenBuildItem(String openedModuleName, String openingModuleName, String... packageNames) {\n        this.openedModuleName = Assert.checkNotEmptyParam(\"openedModuleName\", openedModuleName);\n        this.openingModuleName = Assert.checkNotEmptyParam(\"openingModuleName\", openingModuleName);\n        this.packageNames = Assert.checkNotEmptyParam(\"packageNames\", Set.of(packageNames));\n        if (packageNames.length == 0) {\n            throw new IllegalArgumentException(\"At least one package name must be specified\");\n        }\n        if (ALL_UNNAMED.equals(openedModuleName)) {\n            throw new IllegalArgumentException(\"The unnamed module cannot be opened to other modules\");\n        }\n        if (ALL_UNNAMED.equals(openingModuleName)) {\n            throw new IllegalArgumentException(\n                    \"The unnamed module cannot be used as an opening module identifier: please read the Javadocs for more details\");\n        }\n    }\n\n    public String openedModuleName() {\n        return openedModuleName;\n    }\n\n    public String openingModuleName() {\n        return openingModuleName;\n    }\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/deployment/src/main/java/io/quarkus/deployment/builditem/ModuleOpenBuildItem.java#L44-L80","documentation":"ModuleOpenBuildItem opens packages of one module to another at runtime (JPMS --add-opens equivalent). Both module names must be non-empty and at least one package must be given; the constructor throws IllegalArgumentException when packageNames is empty. (It also rejects using ALL_UNNAMED as the opened module.)","triggerScenarios":"Constructing new ModuleOpenBuildItem(opened, opening) with an empty String[] / zero arguments, or new ModuleOpenBuildItem(\"m\", \"n\", new String[0]).","commonSituations":"Extension code forwarding a config-derived package list that is empty because the config property was unset; calling the varargs constructor with no packages assuming it opens the whole module.","solutions":["Pass the package(s) to open explicitly: new ModuleOpenBuildItem(\"org.foo\", \"io.quarkus\", \"org.foo.internal\").","To open all packages, enumerate them (e.g. from the module's package list) or produce one item per package rather than passing an empty array.","Skip producing the build item when no packages are configured instead of constructing it with an empty list."],"exampleFix":"// before\nbuildProducer.produce(new ModuleOpenBuildItem(\"org.foo\", \"io.quarkus\")); // empty packages\n// after\nbuildProducer.produce(new ModuleOpenBuildItem(\"org.foo\", \"io.quarkus\", \"org.foo.internal\"));","handlingStrategy":"validation","validationCode":"if (packageNames == null || packageNames.length == 0) {\n    return; // or throw with a clear message\n}\nproduce(new ModuleOpenBuildItem(openedModuleName, openingModuleName, packageNames));","typeGuard":"boolean hasPackages(String... packageNames) {\n    return packageNames != null && packageNames.length > 0;\n}","tryCatchPattern":"try {\n    produce(new ModuleOpenBuildItem(opened, opening, packages));\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"At least one package name must be specified\")) {\n        log.warnf(\"No packages configured to open from module '%s'; skipping\", opened);\n        return;\n    }\n    throw e;\n}","preventionTips":["Supply explicit package names from configuration with a non-empty default","Skip item production when the configured package list is empty","To open everything, enumerate the target module's packages instead of passing an empty varargs array","Remember ALL_UNNAMED is invalid as the opened module too; validate both names"],"tags":["quarkus","jpms","modules","validation"],"backgroundTag":"empty-required-argument","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"}