wavetermdev/waveterm · error
error copying wsh binary to bin: %v
Error message
error copying wsh binary to bin: %v
What it means
initCustomShellStartupFilesInternal copies the platform-appropriate wsh binary into <waveDataHome>/bin via utilfn.AtomicRenameCopy (write temp + rename). This error wraps any failure in that copy: source missing/unreadable, destination not writable, cross-device rename issues, or target binary in use (ETXTBSY/Windows lock).
Source
Thrown at pkg/util/shellutil/shellutil.go:458
return err
}
// copy the correct binary to bin
wshFullPath, err := GetLocalWshBinaryPath(wavebase.WaveVersion, runtime.GOOS, runtime.GOARCH)
if err != nil {
log.Printf("error (non-fatal), could not resolve wsh binary path: %v\n", err)
}
if _, err := os.Stat(wshFullPath); err != nil {
log.Printf("error (non-fatal), could not resolve wsh binary %q: %v\n", wshFullPath, err)
return nil
}
wshDstPath := filepath.Join(binDir, "wsh")
if runtime.GOOS == "windows" {
wshDstPath = wshDstPath + ".exe"
}
err = utilfn.AtomicRenameCopy(wshDstPath, wshFullPath, 0755)
if err != nil {
return fmt.Errorf("error copying wsh binary to bin: %v", err)
}
wshBaseName := filepath.Base(wshFullPath)
log.Printf("wsh binary successfully copied from %q to %q\n", wshBaseName, wshDstPath)
return nil
}
func GetShellTypeFromShellPath(shellPath string) string {
shellBase := filepath.Base(shellPath)
if strings.Contains(shellBase, "bash") {
return ShellType_bash
}
if strings.Contains(shellBase, "zsh") {
return ShellType_zsh
}
if strings.Contains(shellBase, "fish") {
return ShellType_fish
}
if strings.Contains(shellBase, "pwsh") || strings.Contains(shellBase, "powershell") {View on GitHub (pinned to a4447c1563)
Solutions
- Verify the source binary exists via GetLocalWshBinaryPath(wavebase.WaveVersion, GOOS, GOARCH) and reinstall/repair Wave if missing.
- Check write permission and free space on the wave bin dir (<data>/bin); fix ownership.
- Stop other running Wave instances/wsh processes that may hold the destination binary open, then retry.
- If the source-stat guard silently skipped (non-fatal log path), rerun after the wsh binary is properly installed.
Example fix
// before: stale running wsh holds the destination lock $ pkill wsh && wave # then init succeeds // after wsh binary successfully copied from "wsh" to ".../bin/wsh"
Defensive patterns
Strategy: retry
Validate before calling
// pre-check source and destination before the copy
src, _ := shellutil.GetLocalWshBinaryPath(version, runtime.GOOS, runtime.GOARCH)
if _, err := os.Stat(src); err != nil { return fmt.Errorf("wsh source missing: %w", err) }
if err := os.MkdirAll(binDir, 0755); err != nil { return err } Try / catch
err := shellutil.InitCustomShellStartupFiles() // or the internal init
if err != nil && strings.Contains(err.Error(), "error copying wsh binary") {
time.Sleep(500 * time.Millisecond) // let AV/running-process lock release
if retryErr := shellutil.InitCustomShellStartupFiles(); retryErr != nil {
return retryErr
}
} Prevention
- Ensure only one Wave instance performs wsh initialization at a time (single-instance lock).
- Reinstall/repair Wave if the bundled wsh binary path is missing for the current version/arch.
- On Windows, exit running wsh processes before upgrading so the destination isn't locked.
- Keep the wave data dir and the install on the same filesystem to avoid rename edge cases.
When it happens
Trigger: Calling initCustomShellStartupFilesInternal (wsh init path) when AtomicRenameCopy(wshDstPath, wshFullPath, 0755) fails: wshFullPath missing despite passing os.Stat, bin dir unwritable, or rename across filesystems.
Common situations: Upgraded Wave package where the bundled wsh path changed; running Wave from a read-only install while the data dir is elsewhere; two Wave instances racing to replace wsh simultaneously; EPERM when overwriting a running executable on Windows.
Related errors
- accessing file %s: %w
- getting absolute path for %s: %w
- reading directory %s: %w
- reading file %s: %w
- tailing log file: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/efde1167c8298819.
Report an issue: GitHub.