{"record":{"id":"5f320d5712b930ee","repo":"dotnet/aspnetcore","slug":"the-send-method-cannot-be-called-if-the-connecti","errorCode":null,"errorMessage":"The 'send' method cannot be called if the connection is not active.","messagePattern":"The 'send' method cannot be called if the connection is not active\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/java/signalr/core/src/main/java/com/microsoft/signalr/HubConnection.java","lineNumber":598,"sourceCode":"                } catch (Exception ex) {\n                    logger.warn(\"Invoking 'onClosed' method failed:\", ex);\n                }\n            }\n        }\n    }\n\n    /**\n     * Invokes a hub method on the server using the specified method name.\n     * Does not wait for a response from the receiver.\n     *\n     * @param method The name of the server method to invoke.\n     * @param args   The arguments to be passed to the method.\n     */\n    public void send(String method, Object... args) {\n        this.state.lock();\n        try {\n            if (this.state.getHubConnectionState() != HubConnectionState.CONNECTED) {\n                throw new RuntimeException(\"The 'send' method cannot be called if the connection is not active.\");\n            }\n            sendInvocationMessage(method, args);\n        } finally {\n            this.state.unlock();\n        }\n    }\n\n    private void sendInvocationMessage(String method, Object[] args) {\n        sendInvocationMessage(method, args, null, false);\n    }\n\n    private void sendInvocationMessage(String method, Object[] args, String id, Boolean isStreamInvocation) {\n        List<String> streamIds = new ArrayList<>();\n        List<Observable> streams = new ArrayList<>();\n        args = checkUploadStream(args, streamIds, streams);\n        InvocationMessage invocationMessage;\n        if (isStreamInvocation) {\n            invocationMessage = new StreamInvocationMessage(null, id, method, args, streamIds);","sourceCodeStart":580,"sourceCodeEnd":616,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/SignalR/clients/java/signalr/core/src/main/java/com/microsoft/signalr/HubConnection.java#L580-L616","documentation":"send() is a fire-and-forget hub invocation. It acquires the connection state lock and refuses to dispatch when the HubConnectionState is anything other than CONNECTED - typically because the connection is still connecting, reconnecting, or has been stopped.","triggerScenarios":"Calling hubConnection.send(method, args) before start() has completed, after stop(), during a reconnect, or after the transport dropped and the state machine moved to CONNECTING/DISCONNECTED.","commonSituations":"Race between start() returning the Single and the user code immediately calling send(); sending from a UI handler that does not wait on the start Completable; sending after a network drop without subscribing to onClosed(...) to re-establish.","solutions":["Await the start() Completable before calling send(): hub.start().await() or .blockingAwait() / subscribe and send in the continuation.","Subscribe to onClosed(...) and re-run start() before retrying the send.","Guard the call: check hub.getConnectionState() == CONNECTED immediately before send (still racy without the lock, so prefer the await approach)."],"exampleFix":"// before\nHubConnection hub = builder.build();\nhub.start();\nhub.send(\"DoThing\", arg); // throws - not yet CONNECTED\n\n// after\nhub.start().blockingAwait(); // or .await()\nhub.send(\"DoThing\", arg);","handlingStrategy":"validation","validationCode":"// Gate send() on the public connection state.\nif (hub.getConnectionState() == HubConnectionState.CONNECTED) {\n  hub.send(method, args);\n} else {\n  // queue or drop; do not call send()\n}","typeGuard":null,"tryCatchPattern":"try {\n  hub.send(method, args);\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"connection is not active\")) {\n    // enqueue for retry after onReconnected\n  } else throw e;\n}","preventionTips":["Always await start() before sending.","Maintain an AtomicBoolean connectedFlag flipped in onClosed/onReconnected.","Queue outbound messages when the flag is false."],"tags":["signalr","java","state","invocation","race-condition"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}