jesseduffield/lazygit · error

CreatePipe (out): %w

Error message

CreatePipe (out): %w

What it means

Second pipe-creation step in StartPty: the pipe that carries the child's stdout/stderr out of the pseudoconsole. If this CreatePipe fails, the already-created stdin pipe (inRead/inWrite) is closed and this wrapped error returns. Same root causes as any CreatePipe failure: kernel handle/memory resources unavailable.

Source

Thrown at pkg/commands/oscommands/pty_windows.go:290

	return h
}

func StartPty(cmd *exec.Cmd, cols, rows uint16) (sp StartedPty, err error) {
	// Two pipes: one for the child's stdin (we never write to it, but ConPTY
	// needs a handle), one for the child's stdout/stderr multiplexed through
	// the pseudoconsole.
	var inRead, inWrite, outRead, outWrite windows.Handle
	if err = windows.CreatePipe(&inRead, &inWrite, nil, 0); err != nil {
		return StartedPty{}, fmt.Errorf("CreatePipe (in): %w", err)
	}
	defer func() {
		if err != nil {
			_ = windows.CloseHandle(inWrite)
		}
	}()
	if err = windows.CreatePipe(&outRead, &outWrite, nil, 0); err != nil {
		_ = windows.CloseHandle(inRead)
		return StartedPty{}, fmt.Errorf("CreatePipe (out): %w", err)
	}
	defer func() {
		if err != nil {
			_ = windows.CloseHandle(outRead)
		}
	}()

	// CreatePseudoConsole dupes the handles it needs internally; we release
	// our references to the child-side ends immediately after.
	//
	// It also spawns the conhost.exe serving the console session, as a
	// direct child of this process. The teardown in Close needs a handle to
	// that conhost (see there), but Windows offers no way to obtain one
	// from the HPCON, so identify it by diffing our conhost children around
	// the call. Open a real handle right away so that pid reuse can't later
	// misdirect the teardown's reap. If identification fails, the handle
	// stays 0 and the teardown skips the reap.
	var hpc, conhost windows.Handle

View on GitHub (pinned to c477a2959b)

Solutions

  1. Free resources: close other PTY-backed processes and retry.
  2. Restart lazygit to reset any accumulated handle leaks.
  3. Check for external limiters (job objects, AV/EDR hooking pipe syscalls) if reproducible.
Defensive patterns

Strategy: fallback

Try / catch

sp, err := oscommands.StartPty(cmd, cols, rows)
if err != nil && strings.Contains(err.Error(), "CreatePipe") {
    // second pipe failed: resources tight; fall back to non-PTY execution
    return runWithoutPty(cmd)
}

Prevention

When it happens

Trigger: windows.CreatePipe failing on the second call within the same StartPty invocation — resource exhaustion hit between the two pipe creations, or job-object handle caps.

Common situations: Handle pressure during bursts of interactive-command spawning; long-running sessions; sandboxed environments.

Related errors


AI-assisted analysis of jesseduffield/lazygit@c477a2959b (2026-08-15). Data as JSON: /api/errors/2aa6b535598f0086. Report an issue: GitHub.