{"record":{"id":"a4cfab289fceeda9","repo":"puppetlabs/puppet","slug":"invalid-option-option","errorCode":null,"errorMessage":"Invalid option '%{option}'","messagePattern":"Invalid option '%(.+?)'","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/file_serving/fileset.rb","lineNumber":108,"sourceCode":"\n  def links=(links)\n    links = links.to_sym\n    # TRANSLATORS \":links\" is a parameter name and should not be translated\n    raise(ArgumentError, _(\"Invalid :links value '%{links}'\") % { links: links }) unless [:manage, :follow].include?(links)\n\n    @links = links\n    @stat_method = @links == :manage ? :lstat : :stat\n  end\n\n  private\n\n  def initialize_from_hash(options)\n    options.each do |option, value|\n      method = option.to_s + \"=\"\n      begin\n        send(method, value)\n      rescue NoMethodError => e\n        raise ArgumentError, _(\"Invalid option '%{option}'\") % { option: option }, e.backtrace\n      end\n    end\n  end\n\n  def initialize_from_request(request)\n    [:links, :ignore, :recurse, :recurselimit, :max_files, :checksum_type].each do |param|\n      if request.options.include?(param) # use 'include?' so the values can be false\n        value = request.options[param]\n      elsif request.options.include?(param.to_s)\n        value = request.options[param.to_s]\n      end\n      next if value.nil?\n\n      value = true if value == \"true\"\n      value = false if value == \"false\"\n      value = Integer(value) if value.is_a?(String) and value =~ /^\\d+$/\n      send(param.to_s + \"=\", value)\n    end","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/file_serving/fileset.rb#L90-L126","documentation":"Fileset's initialize_from_hash dynamically calls `<option>=` for every key in the options hash. A key with no corresponding setter raises NoMethodError, which is re-raised as ArgumentError \"Invalid option\" with the original backtrace. Valid options map to existing attribute writers: path, ignore, links, recurse, recurselimit, max_files, checksum_type.","triggerScenarios":"Puppet::FileServing::Fileset.new('/x', recurse_limit: 2) (typo'd key); passing a generic options hash (from YAML/JSON or method args splats) that contains keys like `server` or `environment` that Fileset does not support.","commonSituations":"Forwarding option hashes meant for other classes into Fileset; typo'd symbol keys; configuration-driven code where the set of keys drifts from the Fileset API after a Puppet upgrade.","solutions":["Check the key against the supported set (path, ignore, links, recurse, recurselimit, max_files, checksum_type) and fix the typo","Whitelist keys before constructing: slice the hash to the known option names","If you meant request-style options, pass a Puppet::Indirector::Request (initialize_from_request only reads known params) instead of a raw hash"],"exampleFix":"# before\nopts = { recurse: true, recurselimit: 2, ignore_fire: '.git' }\nfileset = Puppet::FileServing::Fileset.new('/srv/data', opts)\n\n# after\nopts = { recurse: true, recurselimit: 2, ignore: '.git' }\nfileset = Puppet::FileServing::Fileset.new('/srv/data', opts)","handlingStrategy":"validation","validationCode":"ALLOWED = %i[path ignore links recurse recurselimit max_files checksum_type].freeze\nopts = opts.slice(*ALLOWED) # Hash#slice (Ruby 2.5+)\nfileset = Puppet::FileServing::Fileset.new(path, opts)","typeGuard":"def valid_fileset_options?(opts)\n  opts.is_a?(Hash) && opts.keys.all? { |k| ALLOWED.include?(k.to_sym) }\nend","tryCatchPattern":"begin\n  Puppet::FileServing::Fileset.new(path, opts)\nrescue ArgumentError => e\n  raise unless e.message.start_with?(\"Invalid option\")\n  bad = opts.keys.find { |k| !ALLOWED.include?(k.to_sym) }\n  opts = opts.reject { |k, _| k.to_sym == bad.to_sym }\n  retry\nend","preventionTips":["Pass option hashes you construct, not ones you received for other APIs","Whitelist keys at deserialization boundaries (YAML/JSON config)","Pin the allowed-key list near the Fileset call and update it on Puppet upgrades"],"tags":["puppet","fileset","invalid-option","argumenterror","ruby"],"backgroundTag":"invalid-option-key","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}