dotnet/aspnetcore · error · RuntimeException

The 'invoke' method cannot be called if the connection is no

Error message

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

What it means

A RuntimeException thrown by the parameterless invoke(String method, Object... args) overload (returns Completable) when the connection is not CONNECTED. invoke() registers an InvocationRequest and sends an InvocationMessage expecting a server completion; doing so while disconnected would leave the request pending forever or fail unrecoverably.

Source

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

                streams.add(stream);
            }
        }

        return params.toArray();
    }

    /**
     * Invokes a hub method on the server using the specified method name and arguments.
     *
     * @param method The name of the server method to invoke.
     * @param args The arguments used to invoke the server method.
     * @return A Completable that indicates when the invocation has completed.
     */
    public Completable invoke(String method, Object... args) {
        this.state.lock();
        try {
            if (this.state.getHubConnectionState() != HubConnectionState.CONNECTED) {
                throw new RuntimeException("The 'invoke' method cannot be called if the connection is not active.");
            }

            ConnectionState connectionState = this.state.getConnectionStateUnsynchronized(false);
            String id = connectionState.getNextInvocationId();

            CompletableSubject subject = CompletableSubject.create();
            InvocationRequest irq = new InvocationRequest(null, id);
            connectionState.addInvocation(irq);

            Subject<Object> pendingCall = irq.getPendingCall();

            pendingCall.subscribe(result -> subject.onComplete(),
                    error -> subject.onError(error),
                    () -> subject.onComplete());

            // Make sure the actual send is after setting up the callbacks otherwise there is a race
            // where the map doesn't have the callbacks yet when the response is returned
            sendInvocationMessage(method, args, id, false);

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Ensure start() has completed and state is CONNECTED before invoking.
  2. Guard: if (connection.getConnectionState() == HubConnectionState.CONNECTED) { connection.invoke(...); }.
  3. Defer invocations via a queue flushed on successful (re)connect.

Example fix

// before
connection.invoke("DoWork").blockingAwait(); // throws if not CONNECTED

// after
connection.start().blockingAwait();
if (connection.getConnectionState() == HubConnectionState.CONNECTED) {
    connection.invoke("DoWork").blockingAwait();
}
Defensive patterns

Strategy: validation

Validate before calling

if (connection.getConnectionState() == HubConnectionState.CONNECTED) {
    connection.invoke("method", arg).blockingAwait();
} else {
    // defer or surface a 'not connected' condition to the caller
}

Type guard

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

Try / catch

try {
    connection.invoke("method", arg).blockingAwait();
} catch (RuntimeException e) {
    if (e.getMessage().contains("'invoke' method cannot be called")) {
        // not connected; retry on reconnect or report to caller
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling connection.invoke("method", args) (Completable-returning form) while getConnectionState() != CONNECTED — before start(), after stop(), or during reconnect.

Common situations: Invoking immediately after building without awaiting start(). Invoking from an onClosed handler or error path after disconnect. Reconnect logic racing with state transitions.

Related errors


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