quarkusio/quarkus · error · WebSocketClientException
Unable to obtain the path param for:
Error message
Unable to obtain the path param for:
What it means
During connect, WebSocketConnectorBase.replacePathParameters() substitutes each {param} placeholder in the client endpoint path with values previously supplied via pathParam(). If a placeholder has no corresponding value in the pathParams map (value == null), this WebSocketClientException is thrown naming the missing parameter.
Source
Thrown at extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketConnectorBase.java:175
String paramName = match.substring(1, match.length() - 1);
names.add(paramName);
}
return names;
}
String replacePathParameters(String path) {
if (path.isEmpty()) {
return path;
}
StringBuilder sb = new StringBuilder();
Matcher m = PATH_PARAM_PATTERN.matcher(path);
while (m.find()) {
// Replace {foo} with the param value
String match = m.group();
String paramName = match.substring(1, match.length() - 1);
String val = pathParams.get(paramName);
if (val == null) {
throw new WebSocketClientException("Unable to obtain the path param for: " + paramName);
}
m.appendReplacement(sb, URLEncoder.encode(val, StandardCharsets.UTF_8));
}
m.appendTail(sb);
return path.startsWith("/") ? sb.toString() : "/" + sb.toString();
}
protected WebSocketClientOptions populateClientOptions() {
final WebSocketClientOptions clientOptions;
if (customWebSocketClientOptions != null) {
clientOptions = new WebSocketClientOptions(customWebSocketClientOptions);
} else {
clientOptions = new WebSocketClientOptions();
}
if (config.offerPerMessageCompression()) {
clientOptions.setTryUsePerMessageCompression(true);
if (config.compressionLevel().isPresent()) {
clientOptions.setCompressionLevel(config.compressionLevel().getAsInt());View on GitHub (pinned to e1c734241f)
Solutions
- Call pathParam(name, value) for every placeholder in the endpoint path before connect()
- Compare the @WebSocketClient path placeholders against the pathParam() calls
- Set a default via pathParam() when the value may legitimately be absent
Example fix
// before
@WebSocketClient(path = "/chat/{roomId}")
connector.connect(); // missing roomId
// after
connector.pathParam("roomId", "42").connect(); Defensive patterns
Strategy: validation
Validate before calling
java.util.regex.Matcher m = java.util.regex.Pattern.compile("\\{([^}]+)}").matcher(endpointPath);
java.util.Set<String> required = new java.util.HashSet<>();
while (m.find()) required.add(m.group(1));
// ensure every required name was supplied via pathParam() Try / catch
try {
connector.connect();
} catch (WebSocketClientException e) {
log.error("Missing path param; supply it with pathParam() before connect()", e);
} Prevention
- Provide all path params in one place before calling connect()
- Add a test that connects with fully parameterized paths
- Fail fast at startup by validating declared vs supplied params
- Avoid dynamically altering the endpoint path
When it happens
Trigger: Connecting while the endpoint path contains a {placeholder} for which pathParam() was never called — e.g. forgetting a required param, building the path dynamically, or the annotation path was changed to add a new placeholder.
Common situations: Adding a new placeholder to the @WebSocketClient path without adding a matching pathParam() call in the connector; conditional logic that skips setting a param; config-driven paths.
Related errors
- [%s] is not a valid path parameter in the path %s
- Endpoint URI not set!
- [%s] is not a valid scheme in the base URI %s
- Unable to obtain the config value for:
- Expected a ClientInvocationBuilder
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/17d76e10f419ebaf.
Report an issue: GitHub.