dotnet/aspnetcore · error · Error

A reconnectPolicy has already been set.

Error message

A reconnectPolicy has already been set.

What it means

Thrown by HubConnectionBuilder.withAutomaticReconnect when `this.reconnectPolicy` is already set. The builder enforces a single reconnect policy per connection; calling withAutomaticReconnect a second time on the same builder instance is rejected rather than silently overwriting the first.

Solutions

  1. Call withAutomaticReconnect exactly once per builder.
  2. If you need to merge, compute the final policy before calling and pass it in a single invocation.
  3. Use a fresh HubConnectionBuilder for each connection rather than reusing/mutating one.

Example fix

// before
b.withAutomaticReconnect([0, 2000]).withAutomaticReconnect([0, 1000, 5000]);
// after
b.withAutomaticReconnect([0, 1000, 5000]);
Defensive patterns

Strategy: validation

Validate before calling

function ensurePolicyOnce(b: { reconnectPolicy?: unknown }) {
  if (b.reconnectPolicy) throw new Error("reconnectPolicy already configured");
}

Prevention

When it happens

Trigger: Invoking `.withAutomaticReconnect(...)` twice on the same HubConnectionBuilder — e.g. once with retry delays and once with a custom IRetryPolicy, or calling it in a shared builder factory that runs more than once.

Common situations: Composing builder configuration helpers that each call withAutomaticReconnect, or refactoring and forgetting to remove the earlier call.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/ab89aa20190d18c1. Report an issue: GitHub.

Appendix: source

Thrown at src/SignalR/clients/ts/signalr/src/HubConnectionBuilder.ts:180

     * By default, the client will wait 0, 2, 10 and 30 seconds respectively before trying up to 4 reconnect attempts.
     */
    public withAutomaticReconnect(): HubConnectionBuilder;

    /** Configures the {@link @microsoft/signalr.HubConnection} to automatically attempt to reconnect if the connection is lost.
     *
     * @param {number[]} retryDelays An array containing the delays in milliseconds before trying each reconnect attempt.
     * The length of the array represents how many failed reconnect attempts it takes before the client will stop attempting to reconnect.
     */
    public withAutomaticReconnect(retryDelays: number[]): HubConnectionBuilder;

    /** Configures the {@link @microsoft/signalr.HubConnection} to automatically attempt to reconnect if the connection is lost.
     *
     * @param {IRetryPolicy} reconnectPolicy An {@link @microsoft/signalR.IRetryPolicy} that controls the timing and number of reconnect attempts.
     */
    public withAutomaticReconnect(reconnectPolicy: IRetryPolicy): HubConnectionBuilder;
    public withAutomaticReconnect(retryDelaysOrReconnectPolicy?: number[] | IRetryPolicy): HubConnectionBuilder {
        if (this.reconnectPolicy) {
            throw new Error("A reconnectPolicy has already been set.");
        }

        if (!retryDelaysOrReconnectPolicy) {
            this.reconnectPolicy = new DefaultReconnectPolicy();
        } else if (Array.isArray(retryDelaysOrReconnectPolicy)) {
            this.reconnectPolicy = new DefaultReconnectPolicy(retryDelaysOrReconnectPolicy);
        } else {
            this.reconnectPolicy = retryDelaysOrReconnectPolicy;
        }

        return this;
    }

    /** Configures {@link @microsoft/signalr.HubConnection.serverTimeoutInMilliseconds} for the {@link @microsoft/signalr.HubConnection}.
     *
     * @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.
     */
    public withServerTimeout(milliseconds: number): HubConnectionBuilder {

View on GitHub (pinned to 3600ca084e)