grosser/parallel_tests · error · RuntimeError

Number of processes separated by pipe must be less than or…

Error message

Number of processes separated by pipe must be less than or equal to the total number of processes

What it means

With --specify-groups, each pipe-separated segment claims one process out of the total (-n, defaulting to the CPU count, optionally multiplied). Grouper.specify_groups raises when the number of pipe segments exceeds the total because there are not enough processes to host them.

Solutions

  1. Set -n to at least the number of pipe-separated groups: `parallel_test -n 3 --specify-groups 'a.rb|b.rb|c.rb'`
  2. Or merge groups with commas -- comma means same process, pipe means new process
  3. When the list is dynamic (STDIN '-'), count the pipes and pass -n accordingly

Example fix

# before (2-CPU default)
parallel_test --specify-groups '1_spec.rb|2_spec.rb|3_spec.rb'

# after
parallel_test -n 3 --specify-groups '1_spec.rb|2_spec.rb|3_spec.rb'
Defensive patterns

Strategy: validation

Validate before calling

groups = 'a_spec.rb|b_spec.rb|c_spec.rb'
n = 3
if groups.split('|').count > n
  abort "--specify-groups defines #{groups.split('|').count} groups but only #{n} processes (-n)"
end

Type guard

def specify_groups_fit?(spec_string, num_processes)
  spec_string.split('|').count <= num_processes
end

Try / catch

begin
  ParallelTests::CLI.new.run(args)
rescue RuntimeError => e
  abort "#{e.message} -- raise -n to at least the number of pipe-separated groups"
end

Prevention

When it happens

Trigger: `parallel_test --specify-groups '1_spec.rb|2_spec.rb|3_spec.rb'` on a 2-CPU machine (default -n 2); `parallel_test -n 2 --specify-groups 'a.rb|b.rb|c.rb'`; groups read from STDIN via `--specify-groups -` where the list has more pipes than -n.

Common situations: Hardcoded group lists in CI while the runner's CPU count differs from the author's machine; forgetting that -n defaults to the machine's processor count; appending a new group to the list without bumping -n.

Related errors


AI-assisted analysis of grosser/parallel_tests@a06047856d (2026-08-23). Data as JSON: /api/errors/efc09b94a61ce0dd. Report an issue: GitHub.

Appendix: source

Thrown at lib/parallel_tests/grouper.rb:61

          group_features_by_size(items_to_group(items), groups)
        end

        groups.map! { |g| g[:items].sort }
      end

      private

      def specified_groups(options)
        groups = options[:specify_groups]
        return groups if groups != '-'

        $stdin.read.chomp
      end

      def specify_groups(items, num_groups, options, groups)
        specify_test_process_groups = specified_groups(options).split('|')
        if specify_test_process_groups.count > num_groups
          raise 'Number of processes separated by pipe must be less than or equal to the total number of processes'
        end

        all_specified_tests = specify_test_process_groups.map { |group| group.split(',') }.flatten
        specified_items_found, items = items.partition { |item, _size| all_specified_tests.include?(item) }

        specified_specs_not_found = all_specified_tests - specified_items_found.map(&:first)
        if specified_specs_not_found.any?
          raise "Could not find #{specified_specs_not_found} from --specify-groups in the selected files & folders"
        end

        if specify_test_process_groups.count == num_groups && items.flatten.any?
          raise(
            <<~ERROR
              The number of groups in --specify-groups matches the number of groups from -n but there were other specs
              found in the selected files & folders not specified in --specify-groups. Make sure -n is larger than the
              number of processes in --specify-groups if there are other specs that need to be run. The specs that aren't run:
              #{items.map(&:first)}
            ERROR

View on GitHub (pinned to a06047856d)