quarkusio/quarkus · error · IllegalArgumentException

Path parameter not provided

Error message

Path parameter not provided 

What it means

IllegalArgumentException from replaceParameter when a {template} placeholder in the URI template has no entry (or only a null entry) in the parameter map, and the build is not a template-mode build. JAX-RS requires every URI template parameter to be resolved before build(); leaving one unresolved would produce a literal '{name}' in the URI, which is invalid for a concrete URI.

Source

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

    protected StringBuilder replaceParameter(Map<String, ? extends Object> paramMap, boolean fromEncodedMap, boolean isTemplate,
            String string, StringBuilder builder, boolean encode, boolean encodeSlash) {
        if (string.indexOf('{') == -1) {
            return builder.append(string);
        }
        Matcher matcher = createUriParamMatcher(string);
        int start = 0;
        while (matcher.find()) {
            builder.append(string, start, matcher.start());
            String param = matcher.group(1);
            boolean containsValueForParam = paramMap.containsKey(param);
            if (!containsValueForParam) {
                if (isTemplate) {
                    builder.append(matcher.group());
                    start = matcher.end();
                    continue;
                }
                throw new IllegalArgumentException("Path parameter not provided " + param);
            }
            Object value = paramMap.get(param);
            String stringValue = value != null ? value.toString() : null;
            if (stringValue == null) {
                throw new IllegalArgumentException("Template parameter null: " + param);
            }

            if (encode) {
                if (!fromEncodedMap) {
                    if (encodeSlash)
                        stringValue = Encode.encodePathSegmentAsIs(stringValue);
                    else
                        stringValue = Encode.encodePathAsIs(stringValue);
                } else {
                    if (encodeSlash)
                        stringValue = Encode.encodePathSegmentSaveEncodings(stringValue);
                    else
                        stringValue = Encode.encodePathSaveEncodings(stringValue);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure the map contains a non-null entry for every {placeholder} in the template; print the template and the map keys to diff them
  2. Match key names exactly, including case, with the placeholder names
  3. If a parameter is genuinely optional, build the template conditionally or use build(Object...) with ordered values, or keep the placeholder by building a template URI instead of a concrete one
  4. Add a unit test that builds every client URI template with a complete parameter map

Example fix

// before
URI u = UriBuilder.fromUri("/users/{id}/orders/{orderId}").build(Map.of("id", 7)); // orderId missing
// after
URI u = UriBuilder.fromUri("/users/{id}/orders/{orderId}").build(Map.of("id", 7, "orderId", 42));
Defensive patterns

Strategy: validation

Validate before calling

Set<String> required = extractPlaceholders(template); // regex \{([^}]+)\}
Set<String> missing = new HashSet<>(required);
missing.removeAll(paramMap.keySet());
if (!missing.isEmpty()) throw new IllegalArgumentException("Missing URI template params: " + missing);

Type guard

static boolean hasAllParams(String template, Map<String, ?> params) {
    java.util.regex.Matcher m = java.util.regex.Pattern.compile("\\{([^}]+)\\}").matcher(template);
    while (m.find()) { if (!params.containsKey(m.group(1)) || params.get(m.group(1)) == null) return false; }
    return true;
}

Try / catch

try {
    URI uri = builder.build(params);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Path parameter not provided")) {
        throw new IllegalStateException("Template param missing for " + builder.toTemplate() + ": " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: UriBuilder.build(Map) / buildFromMap / buildString path where the map is missing a key named by a placeholder in the template, or the key exists but maps to null (that exact case reports 'Path parameter not provided' when containsValueForParam is false because null is not 'contained').

Common situations: Renaming a path variable in @Path("/{id}") without updating the map keys; typos in map keys (case mismatch); conditional parameters that are sometimes absent; refactoring from varargs build(...) to build(Map) with wrong keys.

Related errors


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