OrchardCMS/OrchardCore · error · Error

The HubConnection must be in the Disconnected or…

Error message

The HubConnection must be in the Disconnected or Reconnecting state to change the url.

What it means

HubConnection.baseUrl setter throws this when the connection's current state is neither Disconnected nor Reconnecting. The SignalR client only allows retargeting the underlying connection URL while it is not actively Connected, Connecting, or Disconnecting, because changing the endpoint mid-flight would corrupt the negotiated transport. The library throws synchronously from the setter to prevent silently pointing an active connection at a different server.

Solutions

  1. Check hubConnection.state before assigning baseUrl and only set it when it is Disconnected or Reconnecting.
  2. If the connection is active, await hubConnection.stop() first, set baseUrl, then start() again.
  3. Move the baseUrl assignment into the onreconnecting callback (state is Reconnecting there) or use withUrl() before the initial start().
  4. Guard with a try-catch around the setter so an unexpected state does not crash the caller.

Example fix

// before
hubConnection.baseUrl = newUrl; // throws if connected
// after
if (hubConnection.state === HubConnectionState.Disconnected ||
    hubConnection.state === HubConnectionState.Reconnecting) {
  hubConnection.baseUrl = newUrl;
} else {
  await hubConnection.stop();
  hubConnection.baseUrl = newUrl;
  await hubConnection.start();
}
Defensive patterns

Strategy: validation

Validate before calling

const state = connection.state;
if (state !== signalR.HubConnectionState.Disconnected && state !== signalR.HubConnectionState.Reconnecting) {
  throw new Error(`Cannot change baseUrl in state ${state}`);
}
connection.baseUrl = newUrl;

Type guard

function canSetBaseUrl(conn) {
  return conn.state === signalR.HubConnectionState.Disconnected ||
         conn.state === signalR.HubConnectionState.Reconnecting;
}

Try / catch

try {
  connection.baseUrl = newUrl;
} catch (err) {
  if (err.message.includes("Disconnected or Reconnecting")) {
    await connection.stop();
    connection.baseUrl = newUrl;
    await connection.start();
  } else { throw err; }
}

Prevention

When it happens

Trigger: Assigning hubConnection.baseUrl (e.g. to swap to a failover server or update a token-bearing query string) while hubConnection.state is HubConnectionState.Connected, Connecting, or Disconnecting; typically calling baseUrl inside a reconnect handler or a timer without checking state first.

Common situations: Developers rotating auth tokens or server URLs during an active session; calling baseUrl in onreconnecting/onreconnected hooks where the state is actually Connected; retry logic that re-points the URL while a start() promise is still in flight.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/889b70c1f6934c01. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore.Modules/OrchardCore.SignalR/wwwroot/Scripts/signalr.js:1251

    }
    /** Represents the connection id of the {@link HubConnection} on the server. The connection id will be null when the connection is either
     *  in the disconnected state or if the negotiation step was skipped.
     */
    get connectionId() {
        return this.connection ? (this.connection.connectionId || null) : null;
    }
    /** Indicates the url of the {@link HubConnection} to the server. */
    get baseUrl() {
        return this.connection.baseUrl || "";
    }
    /**
     * Sets a new url for the HubConnection. Note that the url can only be changed when the connection is in either the Disconnected or
     * Reconnecting states.
     * @param {string} url The url to connect to.
     */
    set baseUrl(url) {
        if (this._connectionState !== HubConnectionState.Disconnected && this._connectionState !== HubConnectionState.Reconnecting) {
            throw new Error("The HubConnection must be in the Disconnected or Reconnecting state to change the url.");
        }
        if (!url) {
            throw new Error("The HubConnection url must be a valid url.");
        }
        this.connection.baseUrl = url;
    }
    /** Starts the connection.
     *
     * @returns {Promise<void>} A Promise that resolves when the connection has been successfully established, or rejects with an error.
     */
    start() {
        this._startPromise = this._startWithStateTransitions();
        return this._startPromise;
    }
    async _startWithStateTransitions() {
        if (this._connectionState !== HubConnectionState.Disconnected) {
            return Promise.reject(new Error("Cannot start a HubConnection that is not in the 'Disconnected' state."));
        }

View on GitHub (pinned to 4306c0717f)