quarkusio/quarkus · error · IllegalArgumentException
class must be annotated with @Path
Error message
class must be annotated with @Path
What it means
UriBuilderImpl.path(Class) requires the given resource class to carry a JAX-RS @Path annotation, because it derives the URI path segment from ann.value(). When the class has no @Path annotation the builder cannot compute a segment, so it throws this IllegalArgumentException. This mirrors the JAX-RS UriBuilder contract that path(Class) only accepts annotated resource classes.
Source
Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/jaxrs/UriBuilderImpl.java:408
}
public UriBuilder path(String segment) throws IllegalArgumentException {
if (segment == null)
throw new IllegalArgumentException("path is null");
path = paths(encode, path, segment);
return this;
}
@SuppressWarnings("unchecked")
public UriBuilder path(Class resource) throws IllegalArgumentException {
if (resource == null)
throw new IllegalArgumentException("path is null");
Path ann = (Path) resource.getAnnotation(Path.class);
if (ann != null) {
String[] segments = new String[] { ann.value() };
path = paths(true, path, segments);
} else {
throw new IllegalArgumentException("class must be annotated with @Path");
}
return this;
}
public UriBuilder path(Class resource, String method) throws IllegalArgumentException {
if (resource == null)
throw new IllegalArgumentException("resource is null");
if (method == null)
throw new IllegalArgumentException("method is null");
Method theMethod = null;
for (Method m : resource.getMethods()) {
if (m.getName().equals(method)) {
if (theMethod != null && m.isAnnotationPresent(Path.class)) {
throw new IllegalArgumentException("Two methods with the same path " + method);
}
if (m.isAnnotationPresent(Path.class))
theMethod = m;
}View on GitHub (pinned to e1c734241f)
Solutions
- Annotate the class you pass to path(Class) with @Path("/...") and give it a valid path value.
- Pass the correct JAX-RS resource class that actually has @Path.
- If you only want a literal segment, use path(String) instead of path(Class).
- Pre-check the class with resource.isAnnotationPresent(Path.class) before calling path(Class).
Example fix
// before
URI uri = UriBuilder.fromUri(base).path(NotAResource.class).build();
// after
@Path("/orders")
class OrderResource { }
URI uri = UriBuilder.fromUri(base).path(OrderResource.class).build(); Defensive patterns
Strategy: validation
Validate before calling
if (resource == null || !resource.isAnnotationPresent(jakarta.ws.rs.Path.class)) {
throw new IllegalArgumentException(resource + " is not a @Path-annotated JAX-RS resource");
}
builder.path(resource); Type guard
static boolean isPathResource(Class<?> c) {
return c != null && c.isAnnotationPresent(jakarta.ws.rs.Path.class);
} Try / catch
try {
uri = UriBuilder.fromUri(base).path(resourceClass).build();
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("annotated with @Path")) {
throw new IllegalStateException("Class " + resourceClass + " lacks @Path", e);
}
throw e;
} Prevention
- Only pass classes from your JAX-RS resource packages to path(Class)
- Assert resource classes are annotated in an architecture/unit test
- Prefer path(String) for literal segments
- Run reflection checks (isAnnotationPresent) before building
When it happens
Trigger: Calling uriBuilder.path(SomeClass.class) where SomeClass is a plain class (no @jakarta.ws.rs.Path annotation), or passing the wrong class (e.g. a model/DTO or the wrong end of a resource hierarchy) that lacks @Path.
Common situations: Programmatically building client proxies or links from reflection; a refactor renamed/moved the resource class and lost its @Path; using a base interface without @Path; passing an arbitrary class instead of the JAX-RS resource class.
Related errors
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/db518c6b409a5837.
Report an issue: GitHub.