puppetlabs/puppet · error · SystemCallError
SetPriorityClass
Error message
SetPriorityClass
What it means
In Process.setpriority, after OpenProcess succeeds, SetPriorityClass is invoked and a falsy result raises SystemCallError('SetPriorityClass', FFI.errno). Because the monkey patch forwards the value untouched to Windows, passing anything that is not a valid priority-class constant - most commonly Unix nice numbers like -5 or 10 - fails here (usually ERROR_INVALID_PARAMETER, 87).
Source
Thrown at lib/puppet/util/windows/monkey_patches/process.rb:195
# * Process::REALTIME_PRIORITY_CLASS
# * Process::BELOW_NORMAL_PRIORITY_CLASS
# * Process::ABOVE_NORMAL_PRIORITY_CLASS
def setpriority(kind, int, int_priority)
raise TypeError unless kind.is_a?(Integer)
raise TypeError unless int.is_a?(Integer)
raise TypeError unless int_priority.is_a?(Integer)
int = Process.pid if int == 0
handle = OpenProcess(PROCESS_SET_INFORMATION, 0, int)
if handle == 0
raise SystemCallError, FFI.errno, "OpenProcess"
end
begin
result = SetPriorityClass(handle, int_priority)
raise SystemCallError, FFI.errno, "SetPriorityClass" unless result
ensure
FFI::WIN32.CloseHandle(handle)
end
0
end
private
def initialize_defaults
@hash = {
app_name: nil,
creation_flags: 0,
close_handles: true
}
@si_hash = nil
@procinfo = nil
endView on GitHub (pinned to e227c27540)
Solutions
- Pass Windows priority-class constants: Process::IDLE_PRIORITY_CLASS, :BELOW_NORMAL/:NORMAL/:ABOVE_NORMAL_PRIORITY_CLASS, :HIGH_PRIORITY_CLASS, :REALTIME_PRIORITY_CLASS
- Translate Unix nice values explicitly (e.g. nice>0 -> BELOW_NORMAL, nice<0 -> ABOVE_NORMAL) before calling
- Rescue SystemCallError and skip - never let priority tuning abort the main work
Example fix
// before Process.setpriority(:process, pid, 10) # Unix nice value -> SetPriorityClass fails // after Process.setpriority(:process, pid, Process::BELOW_NORMAL_PRIORITY_CLASS)
Defensive patterns
Strategy: validation
Validate before calling
VALID_PRIORITIES = [Process::IDLE_PRIORITY_CLASS, Process::BELOW_NORMAL_PRIORITY_CLASS,
Process::NORMAL_PRIORITY_CLASS, Process::ABOVE_NORMAL_PRIORITY_CLASS,
Process::HIGH_PRIORITY_CLASS, Process::REALTIME_PRIORITY_CLASS].freeze
raise ArgumentError, "not a Windows priority class: #{int_priority}" unless VALID_PRIORITIES.include?(int_priority)
Process.setpriority(:process, pid, int_priority) Type guard
def priority_class?(value) [Process::IDLE_PRIORITY_CLASS, Process::BELOW_NORMAL_PRIORITY_CLASS, Process::NORMAL_PRIORITY_CLASS, Process::ABOVE_NORMAL_PRIORITY_CLASS, Process::HIGH_PRIORITY_CLASS, Process::REALTIME_PRIORITY_CLASS].include?(value) end
Try / catch
begin
Process.setpriority(:process, pid, int_priority)
rescue SystemCallError => e
raise unless e.message.include?('SetPriorityClass')
warn "skipping priority change for #{pid}: #{e.message}"
end Prevention
- Never feed Unix nice values (-20..20) to Windows setpriority
- Translate nice semantics explicitly at your API boundary before calling
- Avoid REALTIME_PRIORITY_CLASS except for trusted, dedicated processes
When it happens
Trigger: Process.setpriority(:process, pid, -5) or (…, 10) using Unix nice semantics; passing 0 or nil as the priority; a REALTIME_PRIORITY_CLASS request from a low-privilege token; a handle whose PROCESS_SET_INFORMATION access was stripped between open and set.
Common situations: Porting Unix scheduling scripts ('nice -n 5') to Windows via this API; config files carrying nice values fed verbatim to setpriority; JRuby/Windows CI differences where the same helper works on Linux.
Related errors
- OpenProcess
- Failed to get child process exit code
- OpenProcess(#{desired_access.to_s(8)}, #{inherit}, #{process
- QueryFullProcessImageNameW(phandle, #{use_win32_path_format}
- RegisterEventSourceW failed to open Windows eventlog
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/cc928d8208a5627d.
Report an issue: GitHub.