quarkusio/quarkus · error · WebSocketException
Global error handlers may not accept @PathParam parameters:
Error message
Global error handlers may not accept @PathParam parameters: %s
What it means
Global error handlers (declared with WebSocketGlobalErrorHandling / global @OnError) are not bound to an endpoint path, so @PathParam parameters cannot be resolved there. If a global error handler declares a @PathParam parameter, the build fails with WebSocketException. Path parameters are only meaningful for callbacks attached to an endpoint with a path template.
Source
Thrown at extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/PathParamCallbackArgument.java:28
import io.quarkus.arc.processor.Annotations;
import io.quarkus.gizmo2.Const;
import io.quarkus.gizmo2.Expr;
import io.quarkus.gizmo2.desc.MethodDesc;
import io.quarkus.websockets.next.WebSocketException;
import io.quarkus.websockets.next.runtime.WebSocketConnectionBase;
class PathParamCallbackArgument implements CallbackArgument {
@Override
public boolean matches(ParameterContext context) {
String name = getParamName(context);
if (name != null) {
if (!context.parameter().type().name().equals(WebSocketDotNames.STRING)) {
throw new WebSocketException("Method parameter annotated with @PathParam must be java.lang.String: "
+ WebSocketProcessor.methodToString(context.parameter().method()));
}
if (context.endpointPath() == null) {
throw new WebSocketException("Global error handlers may not accept @PathParam parameters: "
+ WebSocketProcessor.methodToString(context.parameter().method()));
}
List<String> pathParams = getPathParamNames(context.endpointPath());
if (!pathParams.contains(name)) {
throw new WebSocketException(
String.format(
"@PathParam name [%s] must be used in the endpoint path [%s]: %s", name,
context.endpointPath(),
WebSocketProcessor.methodToString(context.parameter().method())));
}
return true;
}
return false;
}
@Override
public Expr get(InvocationBytecodeContext context) {
String paramName = getParamName(context);View on GitHub (pinned to e1c734241f)
Solutions
- Remove the @PathParam parameter from the global error handler
- Move the error-handling method into the specific @WebSocket endpoint where the path param exists
- Access connection-level information via WebSocketConnection parameters instead of path params
Example fix
// before (global handler)
@OnError
void onError(WebSocketConnection conn, @PathParam("id") String id, Throwable t) { }
// after
@OnError
void onError(WebSocketConnection conn, Throwable t) { } Defensive patterns
Strategy: validation
Validate before calling
// Global error handlers: assert no @PathParam parameters exist
boolean hasPathParam = Arrays.stream(handler.getParameters())
.anyMatch(p -> p.isAnnotationPresent(PathParam.class)); Prevention
- Keep global handlers free of endpoint-specific parameters
- Move handlers needing @PathParam into the specific endpoint
- Use WebSocketConnection for generic context in global handlers
When it happens
Trigger: Declaring @PathParam on a parameter of a global @OnError handler method (one registered globally rather than inside a specific @WebSocket endpoint).
Common situations: Copy-pasting an endpoint-level @OnError method into a global error handler class; wanting the path value in a global handler without realizing it is unavailable.
Related errors
- Method parameter annotated with @PathParam must be java.lang
- Unable to inject @%s callback parameter '%s' declared on %s:
- Unable to inject @%s callback parameter '%s' declared on %s:
- @WebSocket callback method may not accept WebSocketClientCon
- @WebSocketClient callback method may not accept WebSocketCon
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/2ea7800f400422ff.
Report an issue: GitHub.