wavetermdev/waveterm · error
error statting cwd %q: %w
Error message
error statting cwd %q: %w
What it means
checkCwd calls os.Stat(cwd) to confirm the working directory exists and is accessible. If Stat fails (missing directory, permission denied, or path pointing to a file), the error is wrapped as "error statting cwd %q: %w" including the offending path. This prevents the pty spawn from failing deep inside exec with a confusing error.
Source
Thrown at pkg/shellexec/shellexec.go:115
func ExitCodeFromWaitErr(err error) int {
if err == nil {
return 0
}
if exitErr, ok := err.(*exec.ExitError); ok {
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
return status.ExitStatus()
}
}
return -1
}
func checkCwd(cwd string) error {
if cwd == "" {
return fmt.Errorf("cwd is empty")
}
if _, err := os.Stat(cwd); err != nil {
return fmt.Errorf("error statting cwd %q: %w", cwd, err)
}
return nil
}
type PipePty struct {
remoteStdinWrite *os.File
remoteStdoutRead *os.File
}
func (pp *PipePty) Fd() uintptr {
return pp.remoteStdinWrite.Fd()
}
func (pp *PipePty) Name() string {
return "pipe-pty"
}
func (pp *PipePty) Read(p []byte) (n int, err error) {View on GitHub (pinned to a4447c1563)
Solutions
- os.Stat the cwd before starting the process and fall back to home directory if invalid
- Restore/recreate the missing directory or fix permissions (chmod/chown)
- Update the block's saved cwd to an existing path
- If the path moved, migrate the stored cwd value
Example fix
// before
proc, err := shellexec.StartLocalShellProc(ctx, termSize, cmdStr, cmdOpts, savedCwd)
// after
if _, err := os.Stat(savedCwd); err != nil {
savedCwd, _ = os.UserHomeDir()
}
proc, err := shellexec.StartLocalShellProc(ctx, termSize, cmdStr, cmdOpts, savedCwd) Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(cwd)
if err != nil || !info.IsDir() {
cwd, _ = os.UserHomeDir() // fallback to a directory that exists
} Try / catch
proc, err := shellexec.StartLocalShellProc(ctx, termSize, cmdStr, cmdOpts, cwd)
if err != nil && strings.HasPrefix(err.Error(), "error statting cwd") {
cwd, _ = os.UserHomeDir()
proc, err = shellexec.StartLocalShellProc(ctx, termSize, cmdStr, cmdOpts, cwd)
} Prevention
- Stat the cwd before spawn and fall back to home if invalid
- Watch for directory deletion while a block is idle
- Handle moved mounts/network paths by re-resolving cwd on reconnect
When it happens
Trigger: StartLocalShellProc invoked with a cwd path that no longer exists (deleted directory), is a file instead of a directory, or is not readable due to permissions.
Common situations: User deleted or renamed the directory a block was running in; NFS/network mount offline; SSH remote whose directory vanished; cwd stored from a previous session on a different machine.
Related errors
- cwd is empty
- failed to get app directory: %w
- failed to get builder executable path: %w
- build output not found: %w
- failed to read app manifest: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/3c54cd48ceb637e2.
Report an issue: GitHub.