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
- Set -n to at least the number of pipe-separated groups: `parallel_test -n 3 --specify-groups 'a.rb|b.rb|c.rb'`
- Or merge groups with commas -- comma means same process, pipe means new process
- 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
- Compute -n from the group list in CI scripts instead of hardcoding both
- Document comma-vs-pipe semantics (comma = same process, pipe = new process) next to the option
- When reading groups from STDIN ('-'), count pipes first and pass a matching -n
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
- Could not find # from --specify-groups in the selected…
- Number of isolated processes must be >= total number of…
- Can't pass --specify-groups with any of these keys…
- Both options are mutually exclusive: verbose & quiet
- Can't pass --failure-exit-code and --highest-exit-status
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)}
ERRORView on GitHub (pinned to a06047856d)