quarkusio/quarkus · error · WebSocketException

Method parameter annotated with @PathParam must be java.lang

Error message

Method parameter annotated with @PathParam must be java.lang.String: %s

What it means

Parameters annotated with @PathParam in websockets-next callback methods must be of type java.lang.String. If any other type is used, the build fails with WebSocketException naming the offending method. This restriction keeps path parameter extraction simple and type-safe.

Source

Thrown at extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/PathParamCallbackArgument.java:24

import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;

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;
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Change the parameter type to String and parse manually inside the method
  2. Keep numeric IDs as String in the endpoint path template and convert after injection
  3. Check the migration guide if porting from classic websockets/JAX-RS where conversion existed

Example fix

// before
@OnMessage
void onMessage(@PathParam("id") Long id, String msg) { }
// after
@OnMessage
void onMessage(@PathParam("id") String id, String msg) {
  Long parsed = Long.valueOf(id);
}
Defensive patterns

Strategy: validation

Validate before calling

for (Parameter p : callbackMethod.getParameters())
    if (p.isAnnotationPresent(PathParam.class) && p.getType() != String.class)
        throw new IllegalArgumentException("@PathParam must be String: " + p);

Prevention

When it happens

Trigger: Annotating a callback parameter with @PathParam where the declared type is not String (e.g. Integer, Long, UUID, primitives).

Common situations: Assuming automatic conversion like JAX-RS @PathParam; converting REST-style endpoint code to websockets-next endpoints; using numeric IDs typed as long/Integer.

Related errors


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