wavetermdev/waveterm · error
failed to build shell command: %w
Error message
failed to build shell command: %w
What it means
MakeWSLProcessController renders the CommandSpec into a shell command string via BuildShellCommand before creating a wsl.Distro command. If the spec is invalid, it returns 'failed to build shell command' wrapped around the underlying error. No WSL process is ever created.
Source
Thrown at pkg/genconn/wsl-impl.go:45
}
type WSLProcessController struct {
distro *wsl.Distro
cmd *wsl.WslCmd
lock *sync.Mutex
once *sync.Once
stdinPiped bool
stdoutPiped bool
stderrPiped bool
waitErr error
started bool
cmdSpec CommandSpec
}
func MakeWSLProcessController(distro *wsl.Distro, cmdSpec CommandSpec) (*WSLProcessController, error) {
fullCmd, err := BuildShellCommand(cmdSpec)
if err != nil {
return nil, fmt.Errorf("failed to build shell command: %w", err)
}
cmd := distro.WslCommand(context.Background(), fullCmd)
if cmd == nil {
return nil, fmt.Errorf("failed to create WSL command")
}
return &WSLProcessController{
distro: distro,
cmd: cmd,
lock: &sync.Mutex{},
once: &sync.Once{},
cmdSpec: cmdSpec,
}, nil
}
func (w *WSLProcessController) Start() error {
w.lock.Lock()View on GitHub (pinned to a4447c1563)
Solutions
- Read the wrapped BuildShellCommand error to identify the bad spec field.
- Validate CommandSpec (non-empty command, supported shell) before constructing the controller.
- Correct the spec at its source (config file, caller, deserialization).
Example fix
// before
spec := genconn.CommandSpec{} // empty
ctrl, err := genconn.MakeWSLProcessController(distro, spec) // fails
// after
if spec.Command == "" { return errors.New("empty command") }
ctrl, err := genconn.MakeWSLProcessController(distro, genconn.CommandSpec{Command: "ls -la", Shell: "bash"})
if err != nil { return err } Defensive patterns
Strategy: validation
Validate before calling
func validWSLSpec(s genconn.CommandSpec) error {
if s.Command == "" { return errors.New("CommandSpec.Command is empty") }
if s.Shell != "" && s.Shell != "bash" && s.Shell != "sh" { return fmt.Errorf("unsupported WSL shell %q", s.Shell) }
return nil
}
if err := validWSLSpec(spec); err != nil { return err } Try / catch
ctrl, err := genconn.MakeWSLProcessController(distro, spec)
if err != nil {
return fmt.Errorf("WSL controller setup failed (inspect CommandSpec): %w", err)
} Prevention
- Validate CommandSpec before construction; reject empty commands and unknown shells at config load time.
- Use a fixed allowlist of shells for WSL targets.
- Unit-test BuildShellCommand with every spec shape your app generates.
- Fail fast at startup by constructing controllers once and surfacing spec errors early.
When it happens
Trigger: Calling MakeWSLProcessController (directly or via MakeProcessController with a WSL distro) with a CommandSpec that BuildShellCommand rejects — invalid shell name, empty command, or malformed spec fields.
Common situations: Spec built from user input or config with an unsupported shell; empty Command field after trimming; spec deserialized from JSON missing required keys.
Related errors
- failed to build shell command: %w
- invalid term size: %v
- SwapToken is required in CommandOptsType
- No tab view found for the given webContents id
- User redirected to docsite to learn more about ARM64 transla
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/5dc3f78df9f33d12.
Report an issue: GitHub.