quarkusio/quarkus · error · WebSocketException

@OnError callback on @WebSocket must not accept WebSocketCli

Error message

@OnError callback on @WebSocket must not accept WebSocketClientConnection: 

What it means

The mirror of error 2665: an @OnError callback on a server-side @WebSocket endpoint must not accept WebSocketClientConnection. The processor infers the callback target from its connection parameter type and rejects a client connection type on a server endpoint with WebSocketException.

Source

Thrown at extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/WebSocketProcessor.java:1848

        List<AnnotationInstance> annotations = findCallbackAnnotations(index, beanClass, WebSocketDotNames.ON_ERROR);
        if (annotations.isEmpty()) {
            return List.of();
        }
        List<Callback> errorHandlers = new ArrayList<>(annotations.size());
        for (AnnotationInstance annotation : annotations) {
            MethodInfo method = annotation.target().asMethod();
            Target target;
            if (method.parameterTypes().stream().map(Type::name).anyMatch(WebSocketDotNames.WEB_SOCKET_CONNECTION::equals)) {
                target = Target.SERVER;
                if (expectedTarget == Target.CLIENT) {
                    throw new WebSocketException("@OnError callback on @WebSocketClient must not accept WebSocketConnection: "
                            + method.declaringClass() + "." + method.name() + "()");
                }
            } else if (method.parameterTypes().stream().map(Type::name)
                    .anyMatch(WebSocketDotNames.WEB_SOCKET_CLIENT_CONNECTION::equals)) {
                target = Target.CLIENT;
                if (expectedTarget == Target.SERVER) {
                    throw new WebSocketException("@OnError callback on @WebSocket must not accept WebSocketClientConnection: "
                            + method.declaringClass() + "." + method.name() + "()");
                }
            } else {
                target = Target.UNDEFINED;
            }
            Callback callback = new Callback(target, annotation, bean, method,
                    executionModel(method, transformedAnnotations), callbackArguments, transformedAnnotations,
                    endpointPath, index);
            long errorArguments = callback.arguments.stream().filter(ca -> ca instanceof ErrorCallbackArgument).count();
            if (errorArguments != 1) {
                throw new WebSocketException(
                        String.format("@OnError callback must accept exactly one error parameter; found %s: %s",
                                errorArguments, callback.asString()));
            }
            errorHandlers.add(callback);
        }
        return errorHandlers;
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Replace WebSocketClientConnection with WebSocketConnection in the parameter list
  2. Fix the import to io.quarkus.websockets.next.WebSocketConnection
  3. Remove the connection parameter if unused

Example fix

// before (server endpoint)
@OnError
void onError(WebSocketClientConnection conn, Exception e) {}

// after
import io.quarkus.websockets.next.WebSocketConnection;
@OnError
void onError(WebSocketConnection conn, Exception e) {}
Defensive patterns

Strategy: validation

Validate before calling

// In a @WebSocket (server) class, use WebSocketConnection in @OnError
@OnError void onError(WebSocketConnection conn, Throwable t) {}

Prevention

When it happens

Trigger: An @WebSocket (server) class has an @OnError method accepting io.quarkus.websockets.next.WebSocketClientConnection.

Common situations: Copy-pasting from a client endpoint into a server endpoint; wrong auto-import; shared handler base class using the client connection type.

Related errors


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