abhigyanpatwari/GitNexus · error · OSError

CreateJobObjectW failed

Error message

CreateJobObjectW failed

What it means

_WindowsJob.__init__ calls kernel32.CreateJobObjectW(None, None); if it returns a NULL handle the harness raises OSError(get_last_error(), ...). This is a Win32 resource-allocation failure during process spawning for ownership tracking — it can only occur on Windows (os.name == 'nt').

Source

Thrown at eval/workflow_bench/process_control.py:255

        kernel32.AssignProcessToJobObject.restype = wintypes.BOOL
        kernel32.TerminateJobObject.argtypes = [wintypes.HANDLE, wintypes.UINT]
        kernel32.TerminateJobObject.restype = wintypes.BOOL
        kernel32.QueryInformationJobObject.argtypes = [
            wintypes.HANDLE,
            ctypes.c_int,
            ctypes.c_void_p,
            wintypes.DWORD,
            ctypes.POINTER(wintypes.DWORD),
        ]
        kernel32.QueryInformationJobObject.restype = wintypes.BOOL
        kernel32.CloseHandle.argtypes = [wintypes.HANDLE]
        kernel32.CloseHandle.restype = wintypes.BOOL
        ntdll.NtResumeProcess.argtypes = [wintypes.HANDLE]
        ntdll.NtResumeProcess.restype = wintypes.LONG

        handle = kernel32.CreateJobObjectW(None, None)
        if not handle:
            raise OSError(ctypes.get_last_error(), "CreateJobObjectW failed")
        self._kernel32 = kernel32
        self._handle = handle
        ownership_slot[-1] = (process, self, None)
        try:
            limits = JOBOBJECT_EXTENDED_LIMIT_INFORMATION()
            limits.BasicLimitInformation.LimitFlags = 0x00002000  # KILL_ON_JOB_CLOSE
            if not kernel32.SetInformationJobObject(handle, 9, ctypes.byref(limits), ctypes.sizeof(limits)):
                raise OSError(ctypes.get_last_error(), "SetInformationJobObject failed")
            process_handle = wintypes.HANDLE(int(process._handle))  # type: ignore[attr-defined]
            if not kernel32.AssignProcessToJobObject(handle, process_handle):
                raise OSError(ctypes.get_last_error(), "AssignProcessToJobObject failed")
            status = int(ntdll.NtResumeProcess(process_handle))
            if status != 0:
                raise OSError(status, "NtResumeProcess failed")
        except BaseException:
            # The child is still suspended when assignment fails. Kill it
            # before releasing any handle; never retry with job breakaway.
            process.kill()

View on GitHub (pinned to d540b00184)

Solutions

  1. Check the Win32 error code in the OSError (errno attr) — e.g. ERROR_NOT_ENOUGH_MEMORY (8) or ERROR_ACCESS_DENIED (5) — for the specific cause.
  2. Reduce concurrency / leak less: ensure every prior _WindowsJob is close()'d before spawning more.
  3. Disable any AV/EDR rule that blocks Job Object creation, or run the benchmark in an environment that permits it.
  4. Switch the run to a POSIX host (Linux) where the job path is not used.
Defensive patterns

Strategy: try-catch

Validate before calling

# Pre-flight on Windows: check the handle table is not already saturated.
import sys
if sys.platform == 'win32':
    import psutil  # optional
    p = psutil.Process()
    if p.num_handles() > 10_000_000:  # near the per-process ceiling
        raise RuntimeError('handle table saturated; close resources before spawning jobs')

Try / catch

import sys
if sys.platform == 'win32':
    try:
        result = run_managed(cmd, timeout=60)
    except OSError as exc:
        if exc.winerror in (8, 1450):  # ERROR_NOT_ENOUGH_MEMORY / quota lack
            log.error('job creation failed on resource exhaustion: %s', exc)
            # back off and retry once, or fall back to a POSIX host
        raise

Prevention

When it happens

Trigger: Hit on Windows only, in _spawn -> _WindowsJob(process, ownership_slot) when CreateJobObjectW returns 0. Commonly caused by exhausting the process handle table, very low commit / nonpaged pool, or running under a sandbox that blocks job creation.

Common situations: Long-running benchmark loops leak handles and exhaust the per-process handle quota; AV/EDR blocks job-object creation; running under Wine/ReactOS where the call is unimplemented; severe memory pressure during a fan-out of subprocesses.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/f161fac69c738413. Report an issue: GitHub.