quarkusio/quarkus · error · IllegalArgumentException
Predicate already set
Error message
Predicate already set
What it means
The HotDeploymentWatchedFileBuildItem.Builder allows exactly one of location or predicate. Once a predicate has been set, calling setLocation would silently create an ambiguous watcher, so the builder throws IllegalArgumentException 'Predicate already set'.
Source
Thrown at core/deployment/src/main/java/io/quarkus/deployment/builditem/HotDeploymentWatchedFileBuildItem.java:104
}
/**
*
* @return {@code true} if a file change should result in an application restart, {@code false} otherwise
*/
public boolean isRestartNeeded() {
return restartNeeded;
}
public static class Builder {
private String location;
private Predicate<String> locationPredicate;
private boolean restartNeeded = true;
public Builder setLocation(String location) {
if (locationPredicate != null) {
throw new IllegalArgumentException("Predicate already set");
}
this.location = location;
return this;
}
public Builder setLocationPredicate(Predicate<String> locationPredicate) {
if (location != null) {
throw new IllegalArgumentException("Location already set");
}
this.locationPredicate = locationPredicate;
return this;
}
public Builder setRestartNeeded(boolean restartNeeded) {
this.restartNeeded = restartNeeded;
return this;
}
View on GitHub (pinned to e1c734241f)
Solutions
- Choose one mechanism: if you need string matching, use setLocation and drop setLocationPredicate (and vice versa).
- Use a fresh Builder instance per watch entry instead of reusing/reconfiguring one.
- If you must support both, convert the location check into a predicate: p -> p.equals(location) and set only the predicate.
Example fix
// before
HotDeploymentWatchedFileBuildItem item = HotDeploymentWatchedFileBuildItem.builder()
.setLocationPredicate(p -> p.startsWith("config/"))
.setLocation("config/app.yaml")
.build();
// after
HotDeploymentWatchedFileBuildItem item = HotDeploymentWatchedFileBuildItem.builder()
.setLocationPredicate(p -> p.startsWith("config/"))
.build(); Defensive patterns
Strategy: validation
Validate before calling
HotDeploymentWatchedFileBuildItem.Builder b = HotDeploymentWatchedFileBuildItem.builder();
if (location != null) {
b.setLocation(location);
} else if (predicate != null) {
b.setLocationPredicate(predicate);
} else {
return; // nothing to watch
} Try / catch
try {
return builder.setLocation(location).build();
} catch (IllegalArgumentException e) {
if ("Predicate already set".equals(e.getMessage())) {
return HotDeploymentWatchedFileBuildItem.builder().setLocation(location).build();
}
throw e;
} Prevention
- Decide the selector style (string vs predicate) once per watch entry
- Create a fresh Builder for each item; never reconfigure a partially built one
- Wrap builder construction in a helper that accepts exactly one selector
When it happens
Trigger: Chaining builder calls where setLocationPredicate(...) is invoked before setLocation(...), or calling both setters on the same Builder instance.
Common situations: Code paths that merge defaults (predicate) with user config (location) on the same builder; copy-pasted builder chains where the wrong setter was left in.
Related errors
- Location already set
- One of either visitorFunction or inputTransformer must be se
- name cannot be null
- Name cannot start with '/':${name}
- Either location or predicate must be set
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/8c644d1c29971d75.
Report an issue: GitHub.