dotnet/aspnetcore · error · RuntimeException

The 'send' method cannot be called if the connection is not

Error message

The 'send' method cannot be called if the connection is not active.

What it means

A RuntimeException thrown by send(String method, Object... args) when the HubConnection state is not CONNECTED. send() is fire-and-forget and requires an active connection to deliver the InvocationMessage; calling it while CONNECTING/DISCONNECTED would lose the message. The guard fails fast rather than silently dropping.

Source

Thrown at src/SignalR/clients/java/signalr/core/src/main/java/com/microsoft/signalr/HubConnection.java:598

                } catch (Exception ex) {
                    logger.warn("Invoking 'onClosed' method failed:", ex);
                }
            }
        }
    }

    /**
     * Invokes a hub method on the server using the specified method name.
     * Does not wait for a response from the receiver.
     *
     * @param method The name of the server method to invoke.
     * @param args   The arguments to be passed to the method.
     */
    public void send(String method, Object... args) {
        this.state.lock();
        try {
            if (this.state.getHubConnectionState() != HubConnectionState.CONNECTED) {
                throw new RuntimeException("The 'send' method cannot be called if the connection is not active.");
            }
            sendInvocationMessage(method, args);
        } finally {
            this.state.unlock();
        }
    }

    private void sendInvocationMessage(String method, Object[] args) {
        sendInvocationMessage(method, args, null, false);
    }

    private void sendInvocationMessage(String method, Object[] args, String id, Boolean isStreamInvocation) {
        List<String> streamIds = new ArrayList<>();
        List<Observable> streams = new ArrayList<>();
        args = checkUploadStream(args, streamIds, streams);
        InvocationMessage invocationMessage;
        if (isStreamInvocation) {
            invocationMessage = new StreamInvocationMessage(null, id, method, args, streamIds);

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Await connection.start().blockingAwait() (or subscribe and only send on onComplete) before calling send().
  2. Guard each send with a check: if (connection.getConnectionState() == HubConnectionState.CONNECTED) { connection.send(...); }.
  3. Queue outgoing messages during reconnect and flush once state returns to CONNECTED.
  4. Register an onClosed callback to pause sending when disconnected.

Example fix

// before
HubConnection conn = HubConnectionBuilder.create(url).build();
conn.send("Greet", "hi"); // throws: not started yet
conn.start().blockingAwait();

// after
HubConnection conn = HubConnectionBuilder.create(url).build();
conn.start().blockingAwait();
if (conn.getConnectionState() == HubConnectionState.CONNECTED) {
    conn.send("Greet", "hi");
}
Defensive patterns

Strategy: validation

Validate before calling

if (connection.getConnectionState() == HubConnectionState.CONNECTED) {
    connection.send("method", arg);
} else {
    // queue or log; do not call send()
}

Type guard

boolean canSend = connection.getConnectionState() == HubConnectionState.CONNECTED;

Try / catch

try {
    connection.send("method", arg);
} catch (RuntimeException e) {
    if (e.getMessage().contains("'send' method cannot be called")) {
        // not connected; queue the message and retry on reconnect
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling connection.send("method", arg) before start() completes, after stop(), or while the connection is reconnecting/CONNECTING. The state check at line 597 throws immediately.

Common situations: Sending immediately after constructing the HubConnection without awaiting start(). Sending in a callback that fires after the connection dropped. Sending in error-handling code that runs post-disconnect. Reconnect logic that doesn't wait for CONNECTED before resuming sends.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/5f320d5712b930ee. Report an issue: GitHub.