wavetermdev/waveterm · error
unable to obtain remote info from connserver: %w
Error message
unable to obtain remote info from connserver: %w
What it means
The controller sends a RemoteGetInfoCommand RPC (2s timeout) to the remote connserver over the connection's wsh route to learn about the remote environment (e.g. which shell it runs). This error means that RPC failed — the remote wsh/connserver is unreachable, not installed, or too slow to respond.
Source
Thrown at pkg/blockcontroller/durableshellcontroller.go:248
Cols: shellutil.DefaultTermCols,
}
if rtOpts != nil && rtOpts.TermSize.Rows > 0 && rtOpts.TermSize.Cols > 0 {
termSize = rtOpts.TermSize
}
cmdStr := blockMeta.GetString(waveobj.MetaKey_Cmd, "")
cwd := blockMeta.GetString(waveobj.MetaKey_CmdCwd, "")
opts, err := remote.ParseOpts(connName)
if err != nil {
return "", fmt.Errorf("invalid ssh remote name (%s): %w", connName, err)
}
conn := conncontroller.MaybeGetConn(opts)
if conn == nil {
return "", fmt.Errorf("connection %q not found", connName)
}
connRoute := wshutil.MakeConnectionRouteId(connName)
remoteInfo, err := wshclient.RemoteGetInfoCommand(wshclient.GetBareRpcClient(), &wshrpc.RpcOpts{Route: connRoute, Timeout: 2000})
if err != nil {
return "", fmt.Errorf("unable to obtain remote info from connserver: %w", err)
}
shellType := shellutil.GetShellTypeFromShellPath(remoteInfo.Shell)
swapToken := makeSwapToken(ctx, ctx, dsc.BlockId, blockMeta, connName, shellType)
sockName := wavebase.GetPersistentRemoteSockName(wstore.GetClientId())
rpcContext := wshrpc.RpcContext{
ProcRoute: true,
SockName: sockName,
BlockId: dsc.BlockId,
Conn: connName,
}
jwtStr, err := wshutil.MakeClientJWTToken(rpcContext)
if err != nil {
return "", fmt.Errorf("error making jwt token: %w", err)
}
swapToken.RpcContext = &rpcContext
swapToken.Env[wshutil.WaveJwtTokenVarName] = jwtStr
cmdOpts := shellexec.CommandOptsType{
Interactive: true,View on GitHub (pinned to a4447c1563)
Solutions
- Verify wsh is installed on the remote host and the connserver is running.
- Increase tolerance by retrying Start once the link is stable (timeout is hardcoded at 2000ms).
- Test basic SSH connectivity to the remote first.
- Reinstall/upgrade wsh on the remote if the version is incompatible.
Example fix
// before
err := controller.Start(ctx, blockMeta, rtOpts, false) // fails: connserver unreachable
// after
conn := conncontroller.MaybeGetConn(opts)
if conn.DeriveConnStatus().Status != conncontroller.Status_Connected {
return fmt.Errorf("connect the remote before starting the shell")
}
err := controller.Start(ctx, blockMeta, rtOpts, false) Defensive patterns
Strategy: retry
Validate before calling
connRoute := wshutil.MakeConnectionRouteId(connName)
if _, err := wshclient.RemoteGetInfoCommand(wshclient.GetBareRpcClient(), &wshrpc.RpcOpts{Route: connRoute, Timeout: 2000}); err != nil {
return fmt.Errorf("remote connserver not reachable: %w", err)
} Try / catch
err := controller.Start(ctx, meta, rtOpts, false)
if err != nil && strings.Contains(err.Error(), "connserver") {
time.Sleep(time.Second) // brief backoff for slow links
err = controller.Start(ctx, meta, rtOpts, false)
} Prevention
- Install/verify wsh on every remote host before first use
- Allow for >2s latency on VPN/satellite links; retry on first failure
- Monitor remote connserver health as part of connection status
When it happens
Trigger: RemoteGetInfoCommand returns an error: remote connserver not running, wsh not installed on the remote, network drop mid-handshake, or response exceeding the 2000ms timeout.
Common situations: First connection to a new remote where wsh hasn't been installed; slow VPN/high-latency link blowing the 2s timeout; remote daemon crashed; firewall blocking the wsh route.
Related errors
- failed to list workspaces: %v
- failed to list blocks from all %d workspace(s)
- running view command: %w
- starting file stream: %w
- getting file info: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/427d90127fb3a499.
Report an issue: GitHub.