jesseduffield/lazygit · error

CreatePseudoConsole: %w

Error message

CreatePseudoConsole: %w

What it means

StartPty calls CreatePseudoConsole (the ConPTY API, Windows 10 1809+) to set up the pseudoconsole using the two pipe ends. On failure it closes the child-side pipe handles and returns this wrapped error. Typical causes: unsupported/old Windows build, conhost.exe problems, or exhausted console sessions.

Source

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

	// 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
	size := clampPtySize(cols, rows)
	conhostScanMu.Lock()
	conhostsBefore := conhostChildren()
	err = windows.CreatePseudoConsole(size, inRead, outWrite, 0, &hpc)
	if err == nil {
		conhost = openNewConhostChild(conhostsBefore)
	}
	conhostScanMu.Unlock()
	if err != nil {
		_ = windows.CloseHandle(inRead)
		_ = windows.CloseHandle(outWrite)
		return StartedPty{}, fmt.Errorf("CreatePseudoConsole: %w", err)
	}
	_ = windows.CloseHandle(inRead)
	_ = windows.CloseHandle(outWrite)
	defer func() {
		if err != nil {
			windows.ClosePseudoConsole(hpc)
			if conhost != 0 {
				_ = windows.CloseHandle(conhost)
			}
		}
	}()

	// The child goes into a job object so that the teardown in Close can
	// terminate the whole process tree. KILL_ON_JOB_CLOSE makes the OS do
	// that when the last handle to the job is closed, which doubles as a
	// safety net: if lazygit exits without running the teardown, the handle
	// is closed for it and the tree is reaped.
	job, err := windows.CreateJobObject(nil, nil)

View on GitHub (pinned to c477a2959b)

Solutions

  1. Verify Windows 10 1809+ / Server 2019+ (`winver`); on older builds PTY-backed features can't work.
  2. Ensure conhost.exe exists and isn't blocked by policy/AV; try 'conhost.exe' from a terminal.
  3. Sign out/in (or reboot) to reset console session state if it worked before.
  4. Update lazygit — the integration layer here keeps changing with Windows releases.
Defensive patterns

Strategy: fallback

Validate before calling

// Feature-detect ConPTY before attempting StartPty:
func conptyAvailable() bool {
    v := windows.RtlGetVersion() // or syscall GetVersionEx equivalent
    return v.Major > 10 || (v.Major == 10 && v.Build >= 17763) // 1809
}

Try / catch

sp, err := oscommands.StartPty(cmd, cols, rows)
if err != nil {
    if strings.Contains(err.Error(), "CreatePseudoConsole") {
        // pre-1809 Windows or conhost unavailable: run without a pty
        return runWithoutPty(cmd)
    }
    return err
}

Prevention

When it happens

Trigger: CreatePseudoConsole returning an error: running on Windows older than 10 1809 (API missing), conhost.exe missing/blocked, too many active ConPTY sessions, or corrupted console driver state.

Common situations: Old Windows Server or LTSB/LTSC builds predating ConPTY; locked-down machines where conhost is disallowed; terminal-driver issues after RDP/session switches.

Related errors


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