{"record":{"id":"3c07bd1de42e22d4","repo":"puppetlabs/puppet","slug":"hash-keyword-arguments-expected","errorCode":null,"errorMessage":"hash keyword arguments expected","messagePattern":"hash keyword arguments expected","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/windows/monkey_patches/process.rb","lineNumber":216,"sourceCode":"      end\n\n      0\n    end\n\n    private\n\n    def initialize_defaults\n      @hash = {\n        app_name: nil,\n        creation_flags: 0,\n        close_handles: true\n      }\n      @si_hash = nil\n      @procinfo = nil\n    end\n\n    def validate_args(args)\n      raise TypeError, 'hash keyword arguments expected' unless args.is_a?(Hash)\n    end\n\n    def validate_keys(args)\n      args.each do |key, val|\n        key = key.to_s.to_sym\n        raise ArgumentError, \"invalid key '#{key}'\" unless VALID_KEYS.include?(key)\n\n        hash[key] = val\n      end\n    end\n\n    def validate_startup_info\n      hash[:startup_info].each do |key, val|\n        key = key.to_s.to_sym\n        raise ArgumentError, \"invalid startup_info key '#{key}'\" unless VALID_SI_KEYS.include?(key)\n\n        si_hash[key] = val\n      end","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/windows/monkey_patches/process.rb#L198-L234","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)"],"exampleFix":"// before\nProcess.create('notepad.exe')            # String -> TypeError\nProcess.create(:command_line, 'notepad')  # two args -> TypeError\n\n// after\nProcess.create(command_line: 'notepad.exe')  # single Hash argument","handlingStrategy":"type-guard","validationCode":"raise TypeError, 'Process.create expects a single options Hash' unless args.is_a?(Hash)\nProcess.create(args)","typeGuard":"def create_options?(value)\n  value.is_a?(Hash)\nend","tryCatchPattern":"begin\n  info = Process.create(opts)\nrescue TypeError => e\n  raise unless e.message.include?('hash keyword arguments expected')\n  raise 'wrap variadic input into a Hash first: Process.create(command_line: cmd)'\nend","preventionTips":["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"],"tags":["windows","process","typeerror","argument-validation","puppet"],"backgroundTag":"invalid-argument-type","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}