zed-industries/zed · warning

aborting reconnect, because not in state that allows reconne

Error message

aborting reconnect, because not in state that allows reconnecting: {state}

What it means

RemoteClient's reconnect flow only runs from states that still own a remote connection. State::can_reconnect() (crates/remote/src/remote_client.rs:228) is true only for Connected, HeartbeatMissed and ReconnectFailed; calling reconnect from Connecting, Reconnecting, ReconnectExhausted, ServerNotRunning - or with no state set at all - logs and bails with the offending state name (crates/remote/src/remote_client.rs:601).

Source

Thrown at crates/remote/src/remote_client.rs:601

            drop(delegate);
        })
    }

    fn reconnect(&mut self, cx: &mut Context<Self>) -> Result<()> {
        let can_reconnect = self
            .state
            .as_ref()
            .map(|state| state.can_reconnect())
            .unwrap_or(false);
        if !can_reconnect {
            let state = if let Some(state) = self.state.as_ref() {
                state.to_string()
            } else {
                "no state set".to_string()
            };
            log::info!(
                "aborting reconnect, because not in state that allows reconnecting: {state}"
            );
            anyhow::bail!(
                "aborting reconnect, because not in state that allows reconnecting: {state}"
            );
        }

        let state = self.state.take().unwrap();
        let (attempts, remote_connection, delegate) = match state {
            State::Connected {
                remote_connection,
                delegate,
                multiplex_task,
                heartbeat_task,
            }
            | State::HeartbeatMissed {
                remote_connection,
                delegate,
                multiplex_task,
                heartbeat_task,

View on GitHub (pinned to 5a9b9558db)

Solutions

  1. Let the client's own reconnection state machine drive reconnects instead of calling reconnect() manually from every error handler
  2. Before forcing a reconnect, wait until the client leaves Connecting/Reconnecting (check its connection-state API)
  3. After ReconnectExhausted or ServerNotRunning, start a brand-new connection instead of reconnecting the dead one
Defensive patterns

Strategy: validation

Validate before calling

// Only reconnect when the client can actually retry:
// allowed states are Connected, HeartbeatMissed, ReconnectFailed.
// Externally, gate on the client's connection-state API instead of calling reconnect() blindly.
if remote_client.connection_state() == ConnectionState::Disconnected {
    remote_client.reconnect(cx);
}

Try / catch

match remote_client.reconnect(cx) {
    Err(e) if e.to_string().contains("not in state that allows reconnecting") => {
        // benign guard: another reconnect is already in flight - ignore
    }
    other => other?,
}

Prevention

When it happens

Trigger: Invoking RemoteClient::reconnect while the client is Connecting or already Reconnecting (a double reconnect), after reconnect attempts were exhausted (ReconnectExhausted), after the server was detected as not running, or before any state was established.

Common situations: Multiple components reacting to the same disconnect and racing to reconnect; custom retry loops stacked on top of the client's built-in reconnection; reconnecting a client that was never shut down cleanly.

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 zed-industries/zed@5a9b9558db (2026-08-20). Data as JSON: /api/errors/642299390c828e92. Report an issue: GitHub.