dotnet/aspnetcore · error · RuntimeException

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

Error message

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

What it means

A RuntimeException thrown by stream(Type returnType, Class<?> returnClass, String method, Object... args) when the connection is not CONNECTED. stream() registers a STREAM_INVOCATION and returns an Observable<T> of streamed items; starting a stream while disconnected would never yield items and leak the InvocationRequest.

Source

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

     * @param returnType The expected return type of the stream items.
     * @param method The name of the server method to invoke.
     * @param args The arguments used to invoke the server method.
     * @param <T> The expected return type.
     * @return An observable that yields the streaming results from the server.
     */
    public <T> Observable<T> stream(Type returnType, String method, Object ... args) {
        Class<?> returnClass = Utils.typeToClass(returnType);
        return this.<T>stream(returnType, returnClass, method, args);
    }

    @SuppressWarnings("unchecked")
    private <T> Observable<T> stream(Type returnType, Class<?> returnClass, String method, Object ... args) {
        String invocationId;
        InvocationRequest irq;
        this.state.lock();
        try {
            if (this.state.getHubConnectionState() != HubConnectionState.CONNECTED) {
                throw new RuntimeException("The 'stream' method cannot be called if the connection is not active.");
            }

            ConnectionState connectionState = this.state.getConnectionStateUnsynchronized(false);
            invocationId = connectionState.getNextInvocationId();
            irq = new InvocationRequest(returnType, invocationId);
            connectionState.addInvocation(irq);

            AtomicInteger subscriptionCount = new AtomicInteger();
            ReplaySubject<T> subject = ReplaySubject.create();
            Subject<Object> pendingCall = irq.getPendingCall();
            pendingCall.subscribe(result -> {
                        subject.onNext(Utils.<T>cast(returnClass, result));
                    }, error -> subject.onError(error),
                    () -> subject.onComplete());

            Observable<T> observable = subject.doOnSubscribe((subscriber) -> subscriptionCount.incrementAndGet());
            sendInvocationMessage(method, args, invocationId, true);
            return observable.doOnDispose(() -> {

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Ensure start() completed and state == CONNECTED before calling stream().
  2. Guard the call with a state check.
  3. Dispose stream subscriptions on disconnect and resubscribe only after reconnect.

Example fix

// before
Observable<Item> obs = connection.stream(Item.class, "Watch", id); // throws if not CONNECTED
obs.subscribe(...);

// after
connection.start().blockingAwait();
if (connection.getConnectionState() == HubConnectionState.CONNECTED) {
    Observable<Item> obs = connection.stream(Item.class, "Watch", id);
    obs.subscribe(...);
}
Defensive patterns

Strategy: validation

Validate before calling

if (connection.getConnectionState() == HubConnectionState.CONNECTED) {
    Observable<Item> obs = connection.stream(Item.class, "method", arg);
    obs.subscribe(...);
} else {
    // defer subscription until connected
}

Type guard

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

Try / catch

try {
    Observable<Item> obs = connection.stream(Item.class, "method", arg);
} catch (RuntimeException e) {
    if (e.getMessage().contains("'stream' method cannot be called")) {
        // not connected; resubscribe on reconnect
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling connection.stream(ItemType.class, "StreamMethod", args) while getConnectionState() != CONNECTED — before start(), after stop(), or during reconnect.

Common situations: Subscribing to a stream on startup before the connection is established. Streaming after an onClosed event. Reconnect logic that resubscribes before state returns to CONNECTED.

Related errors


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