wavetermdev/waveterm · error

connection %q not found

Error message

connection %q not found

What it means

After parsing SSH opts, startNewJob looks up the actual connection object via conncontroller.MaybeGetConn. This error means no connection with that name is currently registered — the remote profile parses but no live connection record exists for it. The shell cannot be started without a connection backing it.

Source

Thrown at pkg/blockcontroller/durableshellcontroller.go:243

}

func (dsc *DurableShellController) startNewJob(ctx context.Context, blockMeta waveobj.MetaMapType, connName string, rtOpts *waveobj.RuntimeOpts) (string, error) {
	termSize := waveobj.TermSize{
		Rows: shellutil.DefaultTermRows,
		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)

View on GitHub (pinned to a4447c1563)

Solutions

  1. Establish the connection first (connect the remote in the UI / trigger a connect) before starting the shell.
  2. Confirm the remote profile exists in connection settings.
  3. Reconnect the remote and then restart the block.
  4. If the profile is gone, re-point the block at an existing connection.

Example fix

// before
controller.Start(ctx, blockMeta, rtOpts, false) // conn "dev-box" never connected
// after
if conncontroller.MaybeGetConn(remote.ParseOptsMust("dev-box")) == nil {
    conncontroller.ConnectToConn(ctx, "dev-box") // establish first
}
controller.Start(ctx, blockMeta, rtOpts, false)
Defensive patterns

Strategy: validation

Validate before calling

opts, _ := remote.ParseOpts(connName)
if conncontroller.MaybeGetConn(opts) == nil {
    return fmt.Errorf("connect to %q before starting the shell", connName)
}

Try / catch

if err := controller.Start(ctx, meta, rtOpts, false); err != nil {
    if strings.Contains(err.Error(), "not found") {
        // trigger connect flow, then retry Start once
    }
    return err
}

Prevention

When it happens

Trigger: ParseOpts succeeded but MaybeGetConn returns nil: the remote was never connected, the connection was closed/removed, or the conn name refers to a stale profile entry.

Common situations: App restarted and connection registry not yet populated; remote profile deleted while a block still points at it; connection disconnect removed the conn entry.

Related errors


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