quarkusio/quarkus · error · RestClientDefinitionException

Parameter names don't match variable names on ${typeDef}::${

Error message

Parameter names don't match variable names on ${typeDef}::${method}

What it means

Thrown by verifyInterface during build as a RestClientDefinitionException when template.resolveTemplates fails with IllegalArgumentException — i.e. the @Path template references variables that no parameter binds, or a parameter binds a variable that doesn't exist. It is the resolution-stage companion to the parameter/variable count check.

Source

Thrown at extensions/resteasy-classic/resteasy-client/runtime/src/main/java/io/quarkus/restclient/runtime/QuarkusRestClientBuilder.java:644

                    org.jboss.resteasy.annotations.jaxrs.PathParam rePathParam = p
                            .getAnnotation(org.jboss.resteasy.annotations.jaxrs.PathParam.class);
                    String name = rePathParam.value() == null || rePathParam.value()
                            .length() == 0 ? p.getName() : rePathParam.value();
                    paramMap.put(name, "foobar");
                } else if (p.isAnnotationPresent(BeanParam.class)) {
                    verifyBeanPathParam(p.getType(), paramMap);
                }
            }

            if (allVariables.size() != paramMap.size()) {
                throw new RestClientDefinitionException(
                        "Parameters and variables don't match on " + typeDef + "::" + method.getName());
            }

            try {
                template.resolveTemplates(paramMap, false).build();
            } catch (IllegalArgumentException ex) {
                throw new RestClientDefinitionException(
                        "Parameter names don't match variable names on " + typeDef + "::" + method.getName(), ex);
            }

        }
    }

    @Override
    public Configuration getConfiguration() {
        return getConfigurationWrapper();
    }

    @Override
    public RestClientBuilder property(String name, Object value) {
        if (name.startsWith(RESTEASY_PROPERTY_PREFIX)) {
            // Makes it possible to configure some of the ResteasyClientBuilder delegate properties
            String builderMethodName = name.substring(RESTEASY_PROPERTY_PREFIX.length());
            Method builderMethod = Arrays.stream(ResteasyClientBuilder.class.getMethods())
                    .filter(m -> builderMethodName.equals(m.getName()) && m.getParameterCount() >= 1)

View on GitHub (pinned to e1c734241f)

Solutions

  1. Align @PathParam("...") values exactly with the {variable} names in @Path
  2. Provide bindings for variables declared on the class-level @Path as well
  3. Run a local request/test early — this fails at client build time, so a smoke test catches it immediately

Example fix

// before
@Path("/orgs/{orgId}")
@GET
Item get(@PathParam("org") String orgId); // name mismatch
// after
@Path("/orgs/{orgId}")
@GET
Item get(@PathParam("orgId") String orgId);
Defensive patterns

Strategy: validation

Validate before calling

// Resolve check: every {var} in @Path (class + method) must be bound by some @PathParam
Set<String> bound = new HashSet<>();
for (java.lang.reflect.Parameter par : method.getParameters()) {
    PathParam pp = par.getAnnotation(PathParam.class);
    if (pp != null) bound.add(pp.value());
}
Pattern pat = Pattern.compile("\\{([^}]+)\\}");
for (String tpl : new String[]{classLevelPath, methodLevelPath}) {
    if (tpl == null) continue;
    Matcher m2 = pat.matcher(tpl);
    while (m2.find()) if (!bound.contains(m2.group(1)))
        throw new IllegalStateException("Unbound path variable: " + m2.group(1));
}

Try / catch

try {
    client = builder.build(MyClient.class);
} catch (RestClientDefinitionException e) {
    if (e.getMessage().contains("Parameter names don't match variable names")) {
        log.error("Template variable name mismatch: {}", e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: @Path uses {filter} but the method parameter is @PathParam("filterBy") — names differ; a variable appears only in a class-level @Path that the method params don't supply; duplicate variable names with conflicting bindings.

Common situations: Renaming either the template variable or the annotation value but not both; forgetting a class-level {tenant} variable has no bound parameter (class-level vars need @PathParam on the method too in MP REST client); typos in variable names.

Related errors


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