wavetermdev/waveterm · error

ssh client is not connected, cannot install

Error message

ssh client is not connected, cannot install

What it means

InstallWsh requires the underlying *wsl.Distro client to copy the wsh binary into the distro. When conn.GetClient() returns nil there is no active connection handle, so installation cannot proceed and this error is returned immediately (after logging 'ssh client is not connected').

Source

Thrown at pkg/wslconn/wslconn.go:430

		conn.Infof(ctx, "writing conn:askbeforewshinstall=false to settings.json\n")
		meta := waveobj.MetaMapType{
			wconfig.ConfigKey_ConnAskBeforeWshInstall: false,
		}
		setConfigErr := wconfig.SetBaseConfigValue(meta)
		if setConfigErr != nil {
			// this is not a critical error, just log and continue
			log.Printf("warning: error writing to base config file: %v", err)
		}
	}
	return true, nil
}

func (conn *WslConn) InstallWsh(ctx context.Context, osArchStr string) error {
	conn.Infof(ctx, "running installWsh...\n")
	client := conn.GetClient()
	if client == nil {
		conn.Infof(ctx, "ERROR ssh client is not connected, cannot install\n")
		return fmt.Errorf("ssh client is not connected, cannot install")
	}
	var clientOs, clientArch string
	var err error
	if osArchStr != "" {
		clientOs, clientArch, err = GetClientPlatformFromOsArchStr(ctx, osArchStr)
	} else {
		clientOs, clientArch, err = GetClientPlatform(ctx, genconn.MakeWSLShellClient(client))
	}
	if err != nil {
		conn.Infof(ctx, "ERROR detecting client platform: %v\n", err)
	}
	conn.Infof(ctx, "detected remote platform os:%s arch:%s\n", clientOs, clientArch)
	err = CpWshToRemote(ctx, client, clientOs, clientArch)
	if err != nil {
		conn.Infof(ctx, "ERROR copying wsh binary to remote: %v\n", err)
		return fmt.Errorf("error copying wsh binary to remote: %w", err)
	}
	conn.Infof(ctx, "successfully installed wsh\n")

View on GitHub (pinned to a4447c1563)

Solutions

  1. Ensure the distro is connected first: conn.Connect(ctx) / conn.Reconnect(ctx), then retry InstallWsh
  2. Gate the call on conn.WaitForConnect(ctx) or a DeriveConnStatus check for Status_Connected
  3. If using tryEnableWsh flow, just retry the connection — wsh install is re-attempted on the next connect

Example fix

// before
err := conn.InstallWsh(ctx, osArchStr)
// after
if conn.DeriveConnStatus().Status != Status_Connected {
    if err := conn.Connect(ctx); err != nil {
        return err
    }
}
err := conn.InstallWsh(ctx, osArchStr)
Defensive patterns

Strategy: validation

Validate before calling

if conn.DeriveConnStatus().Status != Status_Connected {
    if err := conn.Connect(ctx); err != nil {
        return fmt.Errorf("cannot install wsh: %w", err)
    }
}
// safe to call InstallWsh now

Type guard

func installable(conn *wslconn.WslConn) bool {
    return conn.DeriveConnStatus().Status == wslconn.Status_Connected
}

Try / catch

if err := conn.InstallWsh(ctx, osArchStr); err != nil {
    if strings.Contains(err.Error(), "not connected, cannot install") {
        return fmt.Errorf("reconnect the WSL distro before installing wsh: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling WslConn.InstallWsh (e.g. from tryEnableWsh after StartConnServer reports wsh is missing/outdated) while the distro is disconnected, Connect() hasn't finished, or the client was cleared after a disconnect.

Common situations: Auto-install prompt answered while the connection dropped in the background; racing enable-wsh against a reconnect; calling InstallWsh from custom code before ever connecting the distro.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/8786484eac735c5d. Report an issue: GitHub.