{"record":{"id":"6a0ff16a311bb843","repo":"jesseduffield/lazygit","slug":"createjobobject-w","errorCode":null,"errorMessage":"CreateJobObject: %w","messagePattern":"CreateJobObject: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/oscommands/pty_windows.go","lineNumber":340,"sourceCode":"\t_ = windows.CloseHandle(inRead)\n\t_ = windows.CloseHandle(outWrite)\n\tdefer func() {\n\t\tif err != nil {\n\t\t\twindows.ClosePseudoConsole(hpc)\n\t\t\tif conhost != 0 {\n\t\t\t\t_ = windows.CloseHandle(conhost)\n\t\t\t}\n\t\t}\n\t}()\n\n\t// The child goes into a job object so that the teardown in Close can\n\t// terminate the whole process tree. KILL_ON_JOB_CLOSE makes the OS do\n\t// that when the last handle to the job is closed, which doubles as a\n\t// safety net: if lazygit exits without running the teardown, the handle\n\t// is closed for it and the tree is reaped.\n\tjob, err := windows.CreateJobObject(nil, nil)\n\tif err != nil {\n\t\treturn StartedPty{}, fmt.Errorf(\"CreateJobObject: %w\", err)\n\t}\n\tdefer func() {\n\t\tif err != nil {\n\t\t\t// Kills the child on error paths where it was already assigned\n\t\t\t// to the job; plain handle cleanup before that.\n\t\t\t_ = windows.CloseHandle(job)\n\t\t}\n\t}()\n\tlimits := windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION{\n\t\tBasicLimitInformation: windows.JOBOBJECT_BASIC_LIMIT_INFORMATION{\n\t\t\tLimitFlags: windows.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,\n\t\t},\n\t}\n\tif _, err = windows.SetInformationJobObject(\n\t\tjob, windows.JobObjectExtendedLimitInformation,\n\t\tuintptr(unsafe.Pointer(&limits)), uint32(unsafe.Sizeof(limits)),\n\t); err != nil {\n\t\treturn StartedPty{}, fmt.Errorf(\"SetInformationJobObject: %w\", err)","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/jesseduffield/lazygit/blob/c477a2959b229fbf3284be0d4d2904ab61ec3c94/pkg/commands/oscommands/pty_windows.go#L322-L358","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run lazygit outside the restrictive host (job-aware CI container, some terminal multiplexers) to confirm the job nesting restriction.","Free handles/memory and retry if the machine is under resource pressure.","Report the environment details upstream if plain cmd/PowerShell also fails, since nesting behavior varies by Windows version."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"sp, err := oscommands.StartPty(cmd, cols, rows)\nif err != nil {\n    if strings.Contains(err.Error(), \"CreateJobObject\") {\n        // nested-job restriction (CI/sandbox hosts): run without job-based teardown,\n        // but then kill the child process group yourself on exit\n        return startPtyWithoutJob(cmd, cols, rows)\n    }\n    return err\n}","preventionTips":["Detect job-nesting-restricted hosts (CI runners, containers) and use a teardown path that kills the process tree directly.","Don't rely solely on KILL_ON_JOB_CLOSE if you can't guarantee job creation; always pair with explicit cleanup.","Test PTY spawn in the exact deployment environment, not just a dev desktop."],"tags":["windows","pty","job-object","syscall","process-management"],"backgroundTag":null,"analyzedSha":"c477a2959b229fbf3284be0d4d2904ab61ec3c94","analyzedAt":"2026-08-15T08:34:32.451Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}