{"record":{"id":"18d19c66841e59da","repo":"ruby/ruby","slug":"one-set-in-the-composition-must-be-non-nil","errorCode":null,"errorMessage":"one set in the composition must be non-nil","messagePattern":"one set in the composition must be non-nil","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/rubygems/resolver.rb","lineNumber":82,"sourceCode":"  # flattened into the result ComposedSet.\n\n  def self.compose_sets(*sets)\n    sets.compact!\n\n    sets = sets.flat_map do |set|\n      case set\n      when Gem::Resolver::BestSet then\n        set\n      when Gem::Resolver::ComposedSet then\n        set.sets\n      else\n        set\n      end\n    end\n\n    case sets.length\n    when 0 then\n      raise ArgumentError, \"one set in the composition must be non-nil\"\n    when 1 then\n      sets.first\n    else\n      Gem::Resolver::ComposedSet.new(*sets)\n    end\n  end\n\n  ##\n  # Creates a Resolver that queries only against the already installed gems\n  # for the +needed+ dependencies.\n\n  def self.for_current_gems(needed)\n    new needed, Gem::Resolver::CurrentSet.new\n  end\n\n  ##\n  # Create Resolver object which will resolve the tree starting\n  # with +needed+ Dependency objects.","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/ruby/ruby/blob/0e5b888e1c355f3f728f2659f085820937dada48/lib/rubygems/resolver.rb#L64-L100","documentation":"Gem::Resolver.compose_sets(*sets) compacts nil sets, flattens ComposedSets, and then requires at least one remaining resolver set; zero sets raises ArgumentError ('one set in the composition must be non-nil'). It is primarily an API-contract error for code driving the resolver directly - resolution needs at least one source of specifications.","triggerScenarios":"Gem::Resolver.compose_sets(nil), compose_sets() with no args, or compose_sets(*array) where array contains only nils; also higher-level tooling that builds sets from optional inputs (e.g. all sources disabled) and forwards an empty list to the Resolver.","commonSituations":"Custom installers/dependency tooling over RubyGems internals; configurations where every source is disabled (all `gem sources` removed and no local sets supplied); guard-of-absent-arguments refactors that pass nil instead of a default set.","solutions":["Pass at least one concrete set, e.g. Gem::Resolver.compose_sets(Gem::Resolver::BestSet.new) or Gem::Resolver::IndexSet.new / InstalledSet.new / CurrentSet.new as appropriate","Default nil sets to a sensible fallback before composing: sets << Gem::Resolver::BestSet.new if sets.compact.empty?","If building from user config, validate that at least one source is enabled before constructing the resolver"],"exampleFix":"# before\nset = Gem::Resolver.compose_sets(maybe_set)  # maybe_set is nil\n\n# after\nset = Gem::Resolver.compose_sets(maybe_set || Gem::Resolver::BestSet.new)","handlingStrategy":"type-guard","validationCode":"sets = [git_set, vendor_set, index_set].compact\nsets = [Gem::Resolver::BestSet.new] if sets.empty?\nresolver_set = Gem::Resolver.compose_sets(*sets)","typeGuard":"def resolvable_set?(set)\n  set.is_a?(Gem::Resolver::IndexSet) || set.is_a?(Gem::Resolver::BestSet) || set.is_a?(Gem::Resolver::ComposedSet) || set.is_a?(Gem::Resolver::InstalledSet) || set.is_a?(Gem::Resolver::CurrentSet) || set.is_a?(Gem::Resolver::VendorSet) || set.is_a?(Gem::Resolver::GitSet) || set.is_a?(Gem::Resolver::LockfileSet) || set.is_a?(Gem::Resolver::SourceSet)\nend","tryCatchPattern":"begin\n  set = Gem::Resolver.compose_sets(*sets)\nrescue ArgumentError => e\n  raise if !e.message.include?('non-nil')\n  set = Gem::Resolver.compose_sets(Gem::Resolver::BestSet.new)\nend","preventionTips":["Default optional sets to Gem::Resolver::BestSet.new before composing","Validate resolver configuration contains at least one enabled source before resolving","Never pass raw user-config arrays into compose_sets without compaction and an empty check"],"tags":["rubygems","resolver","api-misuse","null-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"0e5b888e1c355f3f728f2659f085820937dada48","analyzedAt":"2026-08-21T14:25:43.473Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}