clash-verge-rev/clash-verge-rev · critical · anyhow::Error

Sidecar did not become ready

Error message

Sidecar did not become ready

What it means

Thrown inside continue_with_sidecar after start_core_inner succeeded but the running mode did not transition to RunningMode::Sidecar. The core started, but the mode reported by get_running_mode is not Sidecar, meaning the process is not the sidecar the caller asked for (e.g. it became a service-managed core, or stopped immediately).

Source

Thrown at src-tauri/src/core/manager/lifecycle.rs:309

        }
        defer! {
            self.finish_config_update();
        }
        let _life = self.lifecycle_lock.lock().await;
        let status = SERVICE_MANAGER.current().await;
        let mode = self.get_running_mode();
        if !can_allow_sidecar_for_session(&mode, &status) {
            anyhow::bail!("Sidecar continuation is not allowed from {mode:?} / {status:?}");
        }
        Config::suppress_tun_for_session().await;
        Config::generate().await?;
        SERVICE_MANAGER.allow_sidecar_for_session()?;
        // Drop the guard last so an earlier failure cannot leave a running Sidecar unguarded.
        proxy_control::stop_guard().await;
        let result = async {
            self.start_core_inner().await?;
            if !matches!(*self.get_running_mode(), RunningMode::Sidecar) {
                anyhow::bail!("Sidecar did not become ready");
            }
            self.apply_proxy_after_start().await
        }
        .await;
        if let Err(error) = &result {
            // Revoke only the failed Sidecar allowance; its startup says nothing about Service health.
            SERVICE_MANAGER.withdraw_sidecar_allowance();
            if let Err(cleanup_error) = self.rollback_failed_sidecar_transition().await {
                return Err(anyhow::anyhow!(
                    "Sidecar startup failed: {error:#}; failed to clear proxy before rollback: {cleanup_error:#}"
                ));
            }
        }
        result
    }

    pub async fn uninstall_service_and_start_sidecar(&self) -> Result<()> {
        if !self.try_start_config_update() {

View on GitHub (pinned to 5cad0f2799)

Solutions

  1. Check service status and ensure the service is not concurrently starting the core.
  2. Inspect the mode right after start_core_inner in logs to see what it transitioned to.
  3. Retry after the service finishes its current operation or uninstall it.
  4. Verify the start_core_inner branch genuinely launches a sidecar process under the current mode.
Defensive patterns

Strategy: try-catch

Try / catch

if let Err(e) = manager.continue_with_sidecar().await {
    if e.to_string().contains("did not become ready") {
        // the core started in a different mode; check service status and retry
        inspect_mode_mismatch().await;
    }
}

Prevention

When it happens

Trigger: start_core_inner returned Ok but the mode tracking did not flip to Sidecar — e.g. the service intercepted the start, the mode was overwritten by a concurrent transition, or start_core_inner started a service-mode core by mistake.

Common situations: A race between the sidecar allowance and the service manager; the service was still alive and grabbed the core; mode detection reads stale state right after spawn; the sidecar binary path resolved to the service launcher.

Related errors


AI-assisted analysis of clash-verge-rev/clash-verge-rev@5cad0f2799 (2026-08-12). Data as JSON: /api/errors/d49b05fd5d39c7ad. Report an issue: GitHub.