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

  1. Raise the file-descriptor limit (ulimit -n)
  2. Restart the app/Wave process to release leaked fds
  3. Check for fd leaks in controllers that never close pipes
  4. 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

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


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/a85418e179c562d9. Report an issue: GitHub.