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

  1. Annotate the class you pass to path(Class) with @Path("/...") and give it a valid path value.
  2. Pass the correct JAX-RS resource class that actually has @Path.
  3. If you only want a literal segment, use path(String) instead of path(Class).
  4. 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

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.