wavetermdev/waveterm · error

socket path must be absolute: %s

Error message

socket path must be absolute: %s

What it means

SetupDomainSocketRpcClient connects to a Wave RPC server over a domain socket. Before dialing, it expands home-dir prefixes and resolves symlinks, then requires the final path to be absolute. A relative path cannot be used reliably for socket dialing, so it is rejected with this error.

Source

Thrown at pkg/wshutil/wshutil.go:195

	return rtn, writeErrCh, nil
}

func tryTcpSocket(sockName string) (net.Conn, error) {
	addr, err := net.ResolveTCPAddr("tcp", sockName)
	if err != nil {
		return nil, err
	}
	return net.DialTCP("tcp", nil, addr)
}

func SetupDomainSocketRpcClient(sockName string, serverImpl ServerImpl, debugName string) (*WshRpc, error) {
	sockName = wavebase.ExpandHomeDirSafe(sockName)
	resolvedPath, err := filepath.EvalSymlinks(sockName)
	if err == nil {
		sockName = resolvedPath
	}
	if !filepath.IsAbs(sockName) {
		return nil, fmt.Errorf("socket path must be absolute: %s", sockName)
	}
	conn, tcpErr := tryTcpSocket(sockName)
	var unixErr error
	if tcpErr != nil {
		conn, unixErr = net.Dial("unix", sockName)
	}
	if tcpErr != nil && unixErr != nil {
		return nil, fmt.Errorf("failed to connect to tcp or unix domain socket: tcp err:%w: unix socket err: %w", tcpErr, unixErr)
	}
	rtn, errCh, err := SetupConnRpcClient(conn, serverImpl, debugName)
	go func() {
		defer func() {
			panichandler.PanicHandler("SetupDomainSocketRpcClient:closeConn", recover())
		}()
		defer conn.Close()
		err := <-errCh
		if err != nil && err != io.EOF {
			log.Printf("error in domain socket connection: %v\n", err)

View on GitHub (pinned to a4447c1563)

Solutions

  1. Pass an absolute socket path (e.g. "/home/user/.waveterm/run/app.sock") or use "~/..." so ExpandHomeDirSafe resolves it.
  2. Verify the configured path with filepath.IsAbs before calling.
  3. Check the config/source of sockName for a missing leading slash or missing ~ prefix.
  4. If the socket path comes from an env var, ensure it is set to a fully qualified path.

Example fix

// before
conn, _, _ := wshutil.SetupDomainSocketRpcClient(ctx, impl, "run/app.sock", "debug")
// after
sock := "/home/user/.waveterm/run/app.sock" // or "~/\.waveterm/run/app.sock"
conn, _, _ := wshutil.SetupDomainSocketRpcClient(ctx, impl, sock, "debug")
Defensive patterns

Strategy: validation

Validate before calling

sock := wavebase.ExpandHomeDirSafe(sockName)
if !filepath.IsAbs(sock) {
    return fmt.Errorf("socket path must be absolute, got %q", sockName)
}

Try / catch

if _, _, err := SetupDomainSocketRpcClient(ctx, impl, sockName, dbg); err != nil {
    if strings.Contains(err.Error(), "socket path must be absolute") {
        sockName = filepath.Join("/", sockName) // or fix config
        return retryWithAbsolutePath(sockName)
    }
    return err
}

Prevention

When it happens

Trigger: Calling SetupDomainSocketRpcClient (or setupRpcClient/Connect which route through it) with a sockName that is relative after ExpandHomeDirSafe and symlink resolution — e.g. "run/waveterm.sock" or a bare filename without a leading "/" or "~".

Common situations: Config file containing a relative socket path; assuming cwd-relative resolution; env-specific socket paths configured without an absolute prefix.

Related errors


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