wavetermdev/waveterm · error
cannot expand wsh path: %w
Error message
cannot expand wsh path: %w
What it means
getWshPath failed expanding '~/.waveterm/bin/wsh' via wavebase.ExpandHomeDir for a remote server, meaning the user's home directory could not be resolved on the remote host. Used by RemoteStartJobCommand to locate the remote wsh binary.
Source
Thrown at pkg/wshrpc/wshremote/wshremote.go:136
if err := os.MkdirAll(symlinkDir, 0700); err != nil {
return fmt.Errorf("could not create client directory %s: %w", symlinkDir, err)
}
os.Remove(symlinkPath)
if err := os.Symlink(impl.SockName, symlinkPath); err != nil {
return fmt.Errorf("could not create symlink %s -> %s: %w", symlinkPath, impl.SockName, err)
}
impl.Log("created symlink %s -> %s\n", symlinkPath, impl.SockName)
return nil
}
func (impl *ServerImpl) getWshPath() (string, error) {
if impl.IsLocal {
return filepath.Join(wavebase.GetWaveDataDir(), "bin", "wsh"), nil
}
wshPath, err := wavebase.ExpandHomeDir("~/.waveterm/bin/wsh")
if err != nil {
return "", fmt.Errorf("cannot expand wsh path: %w", err)
}
return wshPath, nil
}
func (impl *ServerImpl) BadgeWatchPidCommand(ctx context.Context, data wshrpc.CommandBadgeWatchPidData) error {
if data.Pid <= 0 {
return fmt.Errorf("invalid pid: %d", data.Pid)
}
if data.ORef.IsEmpty() {
return fmt.Errorf("oref is required")
}
if data.BadgeId == "" {
return fmt.Errorf("badgeid is required")
}
go func() {
defer func() {
panichandler.PanicHandler("BadgeWatchPidCommand", recover())
}()View on GitHub (pinned to a4447c1563)
Solutions
- Ensure HOME is set for the SSH user on the remote host
- Use a normal shell account rather than a chrooted/restricted one
- Verify wavebase.ExpandHomeDir behavior for the target platform
- Note: only non-local servers hit this path; local builds return the data dir directly
Defensive patterns
Strategy: validation
Validate before calling
out, err := runOnRemote("echo $HOME")
if err != nil || strings.TrimSpace(out) == "" {
return fmt.Errorf("remote HOME not set; cannot resolve wsh path")
} Try / catch
path, err := impl.getWshPath()
if err != nil {
return fmt.Errorf("remote wsh unavailable (check HOME on remote): %w", err)
} Prevention
- Use SSH accounts with a real login shell and HOME set
- Avoid chrooted/sftp-only accounts for remote connections
- Test remote connectivity with a command that reads $HOME first
When it happens
Trigger: Calling RemoteStartJobCommand on a remote connection where ExpandHomeDir('~/.waveterm/bin/wsh') errors — HOME unset or unparseable for the SSH user.
Common situations: SSH into accounts with no/odd HOME env (restricted shells, nologin users), sftp-only chrooted accounts, Windows remote without proper HOME mapping.
Related errors
- starting file stream: %w
- failed to get stderr pipe: %w
- path cannot start with ~, ., or ..
- failed to expand path: %w
- failed to stat path: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/d6da0df5347b9753.
Report an issue: GitHub.