{"record":{"id":"c940a68b45d5a095","repo":"quarkusio/quarkus","slug":"either-location-or-predicate-must-be-set","errorCode":null,"errorMessage":"Either location or predicate must be set","messagePattern":"Either location or predicate must be set","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/deployment/src/main/java/io/quarkus/deployment/builditem/HotDeploymentWatchedFileBuildItem.java","lineNumber":57,"sourceCode":"     * @see #builder()\n     */\n    public HotDeploymentWatchedFileBuildItem(String location) {\n        this(location, true);\n    }\n\n    /**\n     *\n     * @param location\n     * @param restartNeeded\n     * @see #builder()\n     */\n    public HotDeploymentWatchedFileBuildItem(String location, boolean restartNeeded) {\n        this(location, null, restartNeeded);\n    }\n\n    private HotDeploymentWatchedFileBuildItem(String location, Predicate<String> locationPredicate, boolean restartNeeded) {\n        if (location == null && locationPredicate == null) {\n            throw new IllegalArgumentException(\"Either location or predicate must be set\");\n        }\n        this.location = location;\n        this.locationPredicate = locationPredicate;\n        this.restartNeeded = restartNeeded;\n    }\n\n    /**\n     *\n     * @return a location a file from a reloadable module\n     */\n    public String getLocation() {\n        return location;\n    }\n\n    public boolean hasLocation() {\n        return location != null;\n    }\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/deployment/src/main/java/io/quarkus/deployment/builditem/HotDeploymentWatchedFileBuildItem.java#L39-L75","documentation":"HotDeploymentWatchedFileBuildItem tells live-reload which files to watch. Each item must watch something concrete: either a location string or a location predicate. The private constructor enforces that at least one is set; if both are null it throws IllegalArgumentException rather than producing a useless watch entry.","triggerScenarios":"Calling new HotDeploymentWatchedFileBuildItem(null, restartNeeded) (or the two-arg location variant with a null location), so neither location nor predicate is provided.","commonSituations":"Config-driven code passing an application property straight into the constructor where the property is unset; a builder path that computed a null location and null predicate from an empty config map.","solutions":["Pass a real file location, e.g. new HotDeploymentWatchedFileBuildItem(\"config/application.yaml\", true).","If matching multiple paths, use HotDeploymentWatchedFileBuildItem.builder().setLocationPredicate(path -> path.startsWith(\"config/\"))...build().","Guard call sites: skip producing the build item entirely when the configured location is null/blank instead of constructing it."],"exampleFix":"// before\nString loc = config.watchedFile(); // may be null\nbuildProducer.produce(new HotDeploymentWatchedFileBuildItem(loc, true));\n// after\nString loc = config.watchedFile();\nif (loc != null) {\n    buildProducer.produce(new HotDeploymentWatchedFileBuildItem(loc, true));\n}","handlingStrategy":"validation","validationCode":"if (location == null && predicate == null) {\n    return; // skip producing the watch item\n}\nbuildProducer.produce(new HotDeploymentWatchedFileBuildItem(location, restartNeeded));","typeGuard":"boolean isValidWatchTarget(String location, java.util.function.Predicate<String> predicate) {\n    return location != null || predicate != null;\n}","tryCatchPattern":"try {\n    produce(new HotDeploymentWatchedFileBuildItem(loc, true));\n} catch (IllegalArgumentException e) {\n    if (\"Either location or predicate must be set\".equals(e.getMessage())) {\n        log.warn(\"No watched file configured; skipping hot-deploy watch\");\n        return;\n    }\n    throw e;\n}","preventionTips":["Prefer HotDeploymentWatchedFileBuildItem.builder() so exactly one of location/predicate is set deliberately","Validate config-derived locations for null/blank before constructing the item","Never pass Optional.map results directly into the constructor without orElse handling"],"tags":["quarkus","live-reload","hot-deployment","validation"],"backgroundTag":"missing-required-argument","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"}