{"record":{"id":"1ee93f27a3686dda","repo":"dotnet/aspnetcore","slug":"there-are-no-callbacks-registered-for-the-method","errorCode":null,"errorMessage":"There are no callbacks registered for the method '%s'.","messagePattern":"There are no callbacks registered for the method '(.+?)'\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/java/signalr/core/src/main/java/com/microsoft/signalr/HubConnection.java","lineNumber":1647,"sourceCode":"        public Type getReturnType(String invocationId) {\n            InvocationRequest irq = getInvocation(invocationId);\n            if (irq == null) {\n                return null;\n            }\n\n            return irq.getReturnType();\n        }\n\n        @Override\n        public List<Type> getParameterTypes(String methodName) {\n            List<InvocationHandler> handlers = connection.handlers.get(methodName);\n            if (handlers == null) {\n                logger.warn(\"Failed to find handler for '{}' method.\", methodName);\n                return emptyArray;\n            }\n\n            if (handlers.isEmpty()) {\n                throw new RuntimeException(String.format(\"There are no callbacks registered for the method '%s'.\", methodName));\n            }\n\n            return handlers.get(0).getTypes();\n        }\n\n        private void errorHandshake(Exception error) {\n            lock.lock();\n            try {\n                // If onError is called on a completed subject the global error handler is called\n                if (!(handshakeResponseSubject.hasComplete() || handshakeResponseSubject.hasThrowable())) {\n                    handshakeResponseSubject.onError(error);\n                }\n            } finally {\n                lock.unlock();\n            }\n        }\n    }\n","sourceCodeStart":1629,"sourceCodeEnd":1665,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/SignalR/clients/java/signalr/core/src/main/java/com/microsoft/signalr/HubConnection.java#L1629-L1665","documentation":"A RuntimeException thrown by ConnectionState.getParameterTypes when the handler list for a method name exists but is empty. getParameterTypes is called by the protocol during parseMessages to bind incoming invocation arguments; an empty handler list means the method name resolved but carries no callbacks/parameter types, making argument binding impossible.","triggerScenarios":"During parseMessages, binder.getParameterTypes(target) is called for an incoming InvocationMessage. connection.handlers.get(methodName) returns a non-null but empty list (e.g. all handlers were removed but the list entry remains, or an internal inconsistency), triggering the throw at line 1647.","commonSituations":"A handler was registered then removed via Subscription.dispose() leaving an empty list in the map (depends on CallbackMap implementation). The server invokes a client method right at the moment handlers are being removed/added (race). Internal CallbackMap inconsistency. The %s placeholder names the affected method to aid diagnosis.","solutions":["Ensure at least one handler is registered for methods the server invokes on the client; re-register with connection.on(...) before the server can call them.","Avoid disposing the last handler for a method the server still invokes; either keep a handler or coordinate with the server to stop invoking.","If seen transiently during handler swap, register the new handler before disposing the old one."],"exampleFix":"// before: dispose removes the only handler, server then invokes the method\nSubscription sub = connection.on(\"Notify\", (String m) -> { ... }, String.class);\nsub.dispose(); // now handler list is empty\n// server invokes \"Notify\" -> getParameterTypes throws\n\n// after: register the new handler before disposing the old\nSubscription sub2 = connection.on(\"Notify\", (String m) -> { /* new */ }, String.class);\nsub.dispose(); // list still has sub2","handlingStrategy":"validation","validationCode":"// Ensure handlers are registered before the server can invoke them, and don't dispose\n// the last handler for a server-invoked method.\nconnection.on(\"Notify\", (String m) -> { ... }, String.class);\n// Keep this registration alive while the server may invoke \"Notify\".","typeGuard":null,"tryCatchPattern":"// This error is thrown inside parseMessages and surfaces as a connection error.\n// Subscribe to onClosed to detect it; the fix is to keep handlers registered.\nconnection.onClosed(ex -> {\n    if (ex != null && ex.getMessage().contains(\"no callbacks registered\")) {\n        logger.error(\"Server invoked a method with no handlers; re-register handlers\");\n    }\n});","preventionTips":["Register handlers for all server-to-client methods before calling start().","When swapping handlers, register the new one before disposing the old.","Avoid disposing the last handler for a method the server still invokes.","Keep a registry of required handlers and assert it's populated at startup."],"tags":["signalr","java","handlers","argument-binding","lifecycle","protocol"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}