{"record":{"id":"bd6565659410eeab","repo":"abhigyanpatwari/GitNexus","slug":"queryinformationjobobject-failed","errorCode":null,"errorMessage":"QueryInformationJobObject failed","messagePattern":"QueryInformationJobObject failed","errorType":"exception","errorClass":"OSError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/process_control.py","lineNumber":311,"sourceCode":"                (\"TotalKernelTime\", ctypes.c_longlong),\n                (\"ThisPeriodTotalUserTime\", ctypes.c_longlong),\n                (\"ThisPeriodTotalKernelTime\", ctypes.c_longlong),\n                (\"TotalPageFaultCount\", wintypes.DWORD),\n                (\"TotalProcesses\", wintypes.DWORD),\n                (\"ActiveProcesses\", wintypes.DWORD),\n                (\"TotalTerminatedProcesses\", wintypes.DWORD),\n            ]\n\n        info = JOBOBJECT_BASIC_ACCOUNTING_INFORMATION()\n        returned = wintypes.DWORD()\n        if not self._handle or not self._kernel32.QueryInformationJobObject(\n            self._handle,\n            1,  # JobObjectBasicAccountingInformation\n            ctypes.byref(info),\n            ctypes.sizeof(info),\n            ctypes.byref(returned),\n        ):\n            raise OSError(ctypes.get_last_error(), \"QueryInformationJobObject failed\")\n        return int(info.ActiveProcesses)\n\n    def close(self) -> None:\n        if self._handle:\n            self._kernel32.CloseHandle(self._handle)\n            self._handle = None\n\n\ndef _spawn(\n    command: Sequence[str] | str,\n    *,\n    cwd: Path | str | None,\n    env: Mapping[str, str] | None,\n    shell: bool,\n    pipe_stdin: bool,\n    ownership_slot: list[tuple[subprocess.Popen[bytes], _WindowsJob | None, int | None]],\n) -> tuple[subprocess.Popen[bytes], _WindowsJob | None, str]:\n    flags = 0","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/process_control.py#L293-L329","documentation":"active_processes() queries JobObjectBasicAccountingInformation via QueryInformationJobObject to count live children so the harness can prove ownership. If the handle is unset or the query returns FALSE, OSError(get_last_error(), ...) is raised — the harness refuses to claim ownership is healthy without proof.","triggerScenarios":"Called during abort / shutdown bookkeeping on Windows when self._handle is None (already closed) or the query call fails. The OR short-circuit means a None handle alone triggers it.","commonSituations":"Calling active_processes() after close(); querying a job whose child was already reaped by the OS; struct size mismatch on older Windows.","solutions":["Do not call active_processes() after close() — track lifecycle in the caller.","If OSError.errno is ERROR_INVALID_HANDLE (6) the job is closed; treat as 0 live processes at the caller.","Verify the JOBOBJECT_BASIC_ACCOUNTING_INFORMATION size matches the running Windows version.","Run on Linux where active_processes uses a process-group probe instead."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Only query active_processes while the job is open.\nif job._handle is None:\n    log.debug('job closed; reporting 0 active')\n    return 0\nreturn job.active_processes()","typeGuard":null,"tryCatchPattern":"try:\n    n = job.active_processes()\nexcept OSError as exc:\n    if sys.platform == 'win32' and exc.winerror == 6:  # ERROR_INVALID_HANDLE\n        return 0\n    raise","preventionTips":["Never call active_processes() after close().","Treat a closed job as having 0 live children at the caller.","Add lifecycle assertions before any QueryInformationJobObject call."],"tags":["windows","win32","job-object","process-control","lifecycle"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}