puppetlabs/puppet · error · TypeError
hash keyword arguments expected
Error message
hash keyword arguments expected
What it means
The Process.create monkey patch takes exactly one argument - a Hash of options - and validate_args raises TypeError('hash keyword arguments expected') when it receives anything else. This mirrors the win32-process gem API (Process.create(command_line: 'cmd') passes one Hash). It is a call-shape mistake, raised before any validation of contents or any Win32 call.
Source
Thrown at lib/puppet/util/windows/monkey_patches/process.rb:216
end
0
end
private
def initialize_defaults
@hash = {
app_name: nil,
creation_flags: 0,
close_handles: true
}
@si_hash = nil
@procinfo = nil
end
def validate_args(args)
raise TypeError, 'hash keyword arguments expected' unless args.is_a?(Hash)
end
def validate_keys(args)
args.each do |key, val|
key = key.to_s.to_sym
raise ArgumentError, "invalid key '#{key}'" unless VALID_KEYS.include?(key)
hash[key] = val
end
end
def validate_startup_info
hash[:startup_info].each do |key, val|
key = key.to_s.to_sym
raise ArgumentError, "invalid startup_info key '#{key}'" unless VALID_SI_KEYS.include?(key)
si_hash[key] = val
endView on GitHub (pinned to e227c27540)
Solutions
- Pass a single Hash: Process.create(command_line: 'cmd /c dir')
- Collect kwargs with a double splat (def wrapper(**opts); Process.create(opts); end) so an opts Hash is always forwarded
- Coerce early: raise TypeError in your own wrapper unless args.is_a?(Hash)
Example fix
// before
Process.create('notepad.exe') # String -> TypeError
Process.create(:command_line, 'notepad') # two args -> TypeError
// after
Process.create(command_line: 'notepad.exe') # single Hash argument Defensive patterns
Strategy: type-guard
Validate before calling
raise TypeError, 'Process.create expects a single options Hash' unless args.is_a?(Hash) Process.create(args)
Type guard
def create_options?(value) value.is_a?(Hash) end
Try / catch
begin
info = Process.create(opts)
rescue TypeError => e
raise unless e.message.include?('hash keyword arguments expected')
raise 'wrap variadic input into a Hash first: Process.create(command_line: cmd)'
end Prevention
- Process.create takes exactly one Hash - Process.create(command_line: 'cmd /c dir')
- Under Ruby 3, collect kwargs with **opts and forward opts
- Add an is_a?(Hash) guard in wrapper APIs that accept variadic input
When it happens
Trigger: Calling Process.create('cmd /c dir') with a positional string; passing nil, an Array of pairs, or two separate arguments; under Ruby 3, calling a wrapper defined as def spawn(**opts) that forwards nothing when opts is empty; splatting incorrectly (Process.create(*args) where args is not a single Hash).
Common situations: Code written against Ruby's Process.spawn (variadic) reused with win32-style Process.create; ERB/liquid templates interpolating a string command; API wrappers that accept either form and forward blindly.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- OpenProcess
- SetPriorityClass
- invalid key '#{key}'
- invalid startup_info key '#{key}'
- command_line or app_name must be specified
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/3c07bd1de42e22d4.
Report an issue: GitHub.