wavetermdev/waveterm · error

error setting up domain socket rpc client: %v

Error message

error setting up domain socket rpc client: %v

What it means

After extracting the socket name from the JWT, Connect calls wshutil.SetupDomainSocketRpcClient to dial the Wave Terminal domain socket and establish the wsh RPC channel. This error wraps any failure in that setup: the socket file not existing, permission denied, connection refused, or protocol/handshake problems. It means the vdom client could not establish its IPC transport to the Wave Terminal host process.

Source

Thrown at pkg/waveapp/waveapp.go:181

	if jwtToken == "" {
		return fmt.Errorf("no %s env var set", wshutil.WaveJwtTokenVarName)
	}
	rpcCtx, err := wshutil.ExtractUnverifiedRpcContext(jwtToken)
	if err != nil {
		return fmt.Errorf("error extracting rpc context from %s: %v", wshutil.WaveJwtTokenVarName, err)
	}
	client.RpcContext = rpcCtx
	if client.RpcContext == nil || client.RpcContext.BlockId == "" {
		return fmt.Errorf("no block id in rpc context")
	}
	client.ServerImpl = &WaveAppServerImpl{BlockId: client.RpcContext.BlockId, Client: client}
	sockName, err := wshutil.ExtractUnverifiedSocketName(jwtToken)
	if err != nil {
		return fmt.Errorf("error extracting socket name from %s: %v", wshutil.WaveJwtTokenVarName, err)
	}
	rpcClient, err := wshutil.SetupDomainSocketRpcClient(sockName, client.ServerImpl, "vdomclient")
	if err != nil {
		return fmt.Errorf("error setting up domain socket rpc client: %v", err)
	}
	client.RpcClient = rpcClient
	authRtnData, err := wshclient.AuthenticateCommand(client.RpcClient, jwtToken, &wshrpc.RpcOpts{Route: wshutil.ControlRoute})
	if err != nil {
		return fmt.Errorf("error authenticating rpc connection: %v", err)
	}
	if authRtnData.RouteId == "" {
		return fmt.Errorf("authentication returned empty routeid")
	}
	client.RouteId = authRtnData.RouteId
	return nil
}

func (c *Client) SetRootElem(elem *vdom.VDomElem) {
	c.RootElem = elem
}

func (c *Client) CreateVDomContext(target *vdom.VDomTarget) error {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Confirm Wave Terminal is running and the block that spawned the app is still open.
  2. Restart the app from a fresh Wave block so it gets a current token and socket path.
  3. Check the socket file exists at the path encoded in the token and is accessible (ls -l, permissions).
  4. If in a container/VM, mount or forward the Wave domain socket into the environment.
  5. Read the wrapped %v error to distinguish not-found vs permission-denied vs handshake failure.

Example fix

// before: app outlives Wave restart
// (old token reused, socket gone)
// after: detect stale connection and relaunch from a live block
if _, err := os.Stat(sockPath); err != nil { log.Fatal("wave socket unavailable, relaunch app from Wave block") }
Defensive patterns

Strategy: retry

Validate before calling

if _, err := os.Stat(sockName); err != nil {
    return fmt.Errorf("wave domain socket %q unavailable: %w (is Wave Terminal running?)", sockName, err)
}

Try / catch

rpcClient, err := wshutil.SetupDomainSocketRpcClient(sockName, serverImpl, "vdomclient")
if err != nil {
    return fmt.Errorf("error setting up domain socket rpc client: %v", err)
}

Prevention

When it happens

Trigger: Calling Connect when the Wave domain socket has been deleted (Wave restarted or exited), the socket path from the token points to a different machine/container, file permissions on ~/.waveterm deny access, or the socket listener in Wave is not running.

Common situations: Wave Terminal restarted while the app process kept the old token/socket; running the app inside a container without the socket mounted; user mismatch (socket owned by another user); stale WAVE_JWT_TOKEN after a Wave upgrade changed socket naming.

Related errors


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