wavetermdev/waveterm · error
failed to create stdout pipe: %w
Error message
failed to create stdout pipe: %w
What it means
cmd.StdoutPipe() on the tsunami app process failed, so the controller cannot stream the app's stdout (needed to detect its 'listening' port message). Almost always indicates os.Pipe resource exhaustion.
Source
Thrown at pkg/blockcontroller/tsunamicontroller.go:313
func runTsunamiAppBinary(ctx context.Context, appBinPath string, appPath string, blockMeta waveobj.MetaMapType) (*TsunamiAppProc, error) {
cmd := exec.Command(appBinPath)
cmd.Env = append(os.Environ(), "TSUNAMI_CLOSEONSTDIN=1")
if wavebase.IsDevMode() {
cmd.Env = append(cmd.Env, "TSUNAMI_CORS="+tsunamiutil.DevModeCorsOrigins)
}
// Add TsunamiEnv variables if configured
tsunamiEnv := blockMeta.GetMap(waveobj.MetaKey_TsunamiEnv)
for key, value := range tsunamiEnv {
if strValue, ok := value.(string); ok {
cmd.Env = append(cmd.Env, key+"="+strValue)
}
}
stdoutPipe, err := cmd.StdoutPipe()
if err != nil {
return nil, fmt.Errorf("failed to create stdout pipe: %w", err)
}
stderrPipe, err := cmd.StderrPipe()
if err != nil {
return nil, fmt.Errorf("failed to create stderr pipe: %w", err)
}
stdinPipe, err := cmd.StdinPipe()
if err != nil {
return nil, fmt.Errorf("failed to create stdin pipe: %w", err)
}
appName := build.GetAppName(appPath)
lineBuffer := utilds.MakeMultiReaderLineBuffer(1000)
portChan := make(chan int, 1)
portFound := false
View on GitHub (pinned to a4447c1563)
Solutions
- Raise the file-descriptor limit (ulimit -n)
- Restart the app/Wave process to release leaked fds
- Check for fd leaks in controllers that never close pipes
- Retry starting the block after closing unused blocks
Defensive patterns
Strategy: retry
Validate before calling
// check headroom: fds in use vs limit
f, _ := os.Open("/proc/self/status") // verify FDSize/open fds on Linux Try / catch
proc, err := runTsunamiAppBinary(ctx, bin, app, meta)
if err != nil && strings.Contains(err.Error(), "failed to create stdout pipe") {
// free fds / raise ulimit, then retry
} Prevention
- Keep ulimit -n high (e.g. 10240) for the Wave process
- Close idle blocks to release pipes
- Audit controllers for unclosed pipe leaks
When it happens
Trigger: runTsunamiAppBinary calls cmd.StdoutPipe() and receives a non-nil error, typically EMFILE (too many open files).
Common situations: Long-running Wave session leaking file descriptors; system-wide fd limit (ulimit -n) reached.
Related errors
- failed to create stderr pipe: %w
- failed to get stdout pipe: %w
- failed to get stderr pipe: %w
- cannot write job auth token: %w
- procinfo: process not found
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/a85418e179c562d9.
Report an issue: GitHub.