quarkusio/quarkus · error · IllegalArgumentException

Two methods with the same path

Error message

Two methods with the same path 

What it means

When resolving path(Class, String) the builder scans public methods for the given name and keeps the last one annotated with @Path. If it encounters a second @Path-annotated method with the same name it cannot disambiguate which path to use, so it throws this IllegalArgumentException naming the ambiguous method.

Source

Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/jaxrs/UriBuilderImpl.java:422

        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;
            }
        }
        if (theMethod == null)
            throw new IllegalArgumentException("No public method annotated with @Path " + resource.getName() + " " + method);
        return path(theMethod);
    }

    public UriBuilder path(Method method) throws IllegalArgumentException {
        if (method == null) {
            throw new IllegalArgumentException("method is null");
        }
        Path ann = method.getAnnotation(Path.class);
        if (ann != null) {
            path = paths(encode, path, ann.value());
        } else {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Rename one of the overloaded methods so each @Path-annotated name is unique in the class.
  2. Make sure only one same-named method is annotated with @Path (overloads without @Path are fine for this API).
  3. Call path(Method) with the specific resolved Method object instead of path(Class, name).
  4. Check superclass/interface methods pulled in by getMethods() that also carry @Path.

Example fix

// before
@Path("/{id}") public Order get(String id) {...}
@Path("/{id}") public Order get(UUID id) {...}
builder.path(OrderResource.class, "get"); // ambiguous
// after
@Path("/{id}") public Order get(String id) {...}
@Path("/{id}") public Order getByUuid(UUID id) {...}
builder.path(OrderResource.class, "get");
Defensive patterns

Strategy: validation

Validate before calling

long count = Arrays.stream(OrderResource.class.getMethods())
    .filter(m -> m.getName().equals(methodName) && m.isAnnotationPresent(Path.class))
    .count();
if (count > 1) throw new IllegalStateException("Ambiguous @Path methods named " + methodName);

Type guard

static boolean unambiguousPathMethod(Class<?> c, String name) {
    return Arrays.stream(c.getMethods())
        .filter(m -> m.getName().equals(name) && m.isAnnotationPresent(Path.class))
        .count() == 1;
}

Try / catch

try {
    uri = builder.path(OrderResource.class, methodName).build();
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Two methods with the same path")) {
        throw new IllegalStateException("Rename one of the overloaded @Path methods: " + methodName, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A resource class has two public methods with the same name where more than one carries @Path — e.g. overloaded resource methods both annotated @Path("/{id}") with different signatures, then calling path(Resource.class, "name").

Common situations: Overloaded REST endpoints differing only in parameter types (e.g. @GET @Path("/x") versions taking String vs UUID); accidental copy-paste duplication of an endpoint method; inheritance bringing in a same-name @Path method from a superclass.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/866077548efe107a. Report an issue: GitHub.