jesseduffield/lazygit · error

CreateJobObject: %w

Error message

CreateJobObject: %w

What it means

After the pseudoconsole exists, StartPty creates a Job Object (with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE) so closing the job later terminates the whole child process tree — and as a safety net if lazygit itself dies. If CreateJobObject fails, the error is wrapped and the deferred cleanups tear down the pseudoconsole and handles created so far.

Source

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

	_ = 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)
	if err != nil {
		return StartedPty{}, fmt.Errorf("CreateJobObject: %w", err)
	}
	defer func() {
		if err != nil {
			// Kills the child on error paths where it was already assigned
			// to the job; plain handle cleanup before that.
			_ = windows.CloseHandle(job)
		}
	}()
	limits := windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION{
		BasicLimitInformation: windows.JOBOBJECT_BASIC_LIMIT_INFORMATION{
			LimitFlags: windows.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,
		},
	}
	if _, err = windows.SetInformationJobObject(
		job, windows.JobObjectExtendedLimitInformation,
		uintptr(unsafe.Pointer(&limits)), uint32(unsafe.Sizeof(limits)),
	); err != nil {
		return StartedPty{}, fmt.Errorf("SetInformationJobObject: %w", err)

View on GitHub (pinned to c477a2959b)

Solutions

  1. Run lazygit outside the restrictive host (job-aware CI container, some terminal multiplexers) to confirm the job nesting restriction.
  2. Free handles/memory and retry if the machine is under resource pressure.
  3. Report the environment details upstream if plain cmd/PowerShell also fails, since nesting behavior varies by Windows version.
Defensive patterns

Strategy: fallback

Try / catch

sp, err := oscommands.StartPty(cmd, cols, rows)
if err != nil {
    if strings.Contains(err.Error(), "CreateJobObject") {
        // nested-job restriction (CI/sandbox hosts): run without job-based teardown,
        // but then kill the child process group yourself on exit
        return startPtyWithoutJob(cmd, cols, rows)
    }
    return err
}

Prevention

When it happens

Trigger: windows.CreateJobObject returning an error: the process is already subject to a job that disallows nested job creation, or handle/memory exhaustion at this stage.

Common situations: Running lazygit inside a CI runner, Docker/WSL wrapper, sandbox, or another job-hierarchy that sets JOB_OBJECT_LIMIT_BREAKAWAY_OK off / silent-breakaway-allowed off, blocking new job objects.

Related errors


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