grosser/parallel_tests · error · RuntimeError
Both options are mutually exclusive: verbose & quiet
Error message
Both options are mutually exclusive: verbose & quiet
What it means
parallel_tests validates its CLI options right after OptionParser parses the command line. --verbose turns on debug output while --quiet suppresses everything except the raw test output, so the two verbosity levels contradict each other and parse_options! raises a plain RuntimeError when both options hash keys are set.
Source
Thrown at lib/parallel_tests/cli.rb:347
TEXT
) { |limit| options[:test_file_limit] = limit }
opts.on("--verbose", "Print debug output") { options[:verbose] = true }
opts.on("--verbose-command", "Combines options --verbose-process-command and --verbose-rerun-command") { options.merge! verbose_process_command: true, verbose_rerun_command: true }
opts.on("--verbose-process-command", "Print the command that will be executed by each process before it begins") { options[:verbose_process_command] = true }
opts.on("--verbose-rerun-command", "After a process fails, print the command executed by that process") { options[:verbose_rerun_command] = true }
opts.on("--quiet", "Print only tests output") { options[:quiet] = true }
opts.on("-v", "--version", "Show Version") do
puts ParallelTests::VERSION
exit 0
end
opts.on("-h", "--help", "Show this.") do
puts opts
exit 0
end
end.parse!(argv)
raise "Both options are mutually exclusive: verbose & quiet" if options[:verbose] && options[:quiet]
if options[:count] == 0
options.delete(:count)
options[:non_parallel] = true
end
files, remaining = extract_file_paths(argv)
unless options[:execute]
if files.empty?
default_test_folder = @runner.default_test_folder
if File.directory?(default_test_folder)
files = [default_test_folder]
else
abort "Pass files or folders to run"
end
end
options[:files] = files.map { |file_path| Pathname.new(file_path).cleanpath.to_s }
endView on GitHub (pinned to a06047856d)
Solutions
- Remove one of the two flags from the command / PARALLEL_TEST_OPTS string -- decide whether you want debug output or clean output
- If you need targeted verbosity, replace --verbose with --verbose-process-command or --verbose-rerun-command, which are compatible with --quiet
- Grep the repo (CI yaml, .rake files, Makefile, scripts/) for both flags so the fix covers every entry point
Example fix
# before PARALLEL_TEST_OPTS="--verbose --quiet" rake parallel:spec # after PARALLEL_TEST_OPTS="--quiet" rake parallel:spec
Defensive patterns
Strategy: validation
Validate before calling
# Ruby: reject the contradictory pair before invoking the CLI
opts = ENV.fetch('PARALLEL_TEST_OPTS', '').shellsplit
if opts.include?('--verbose') && opts.include?('--quiet')
abort 'parallel_tests: --verbose and --quiet are mutually exclusive'
end
system('parallel_test', *opts) Type guard
# Predicate guarding an argv meant for parallel_tests
def parallel_tests_args_valid?(argv)
!(argv.include?('--verbose') && argv.include?('--quiet'))
end Try / catch
begin
ParallelTests::CLI.new.run(args)
rescue RuntimeError => e
abort "parallel_tests option error: #{e.message}" # fail fast, surface the CLI's own hint
end Prevention
- Keep all parallel_tests flags in one shared constant or ENV var instead of concatenating several sources
- Prefer the narrow --verbose-process-command / --verbose-rerun-command flags over --verbose in CI so they cannot collide with --quiet
- Add a CI lint step that greps option strings for known conflicting pairs
When it happens
Trigger: Run the CLI with both flags, e.g. `parallel_test --verbose --quiet spec/`, or set both via an option string like PARALLEL_TEST_OPTS="--verbose --quiet" feeding `rake parallel:spec`; programmatically, `ParallelTests::CLI.new.run(['--verbose', '--quiet'])` hits the same raise at lib/parallel_tests/cli.rb:347.
Common situations: CI option strings that accreted flags over time (--quiet added for clean logs, --verbose added later while debugging and never removed); rake tasks in lib/tasks that merge arguments from several ENV vars; command lines copy-pasted from runbooks or other CI jobs.
Related errors
- Can't pass --failure-exit-code and --highest-exit-status
- --group-by found and --single-process are not supported
- --group-by #{allowed.join(" or ")} is required for --only-gr
- Can't pass --specify-groups with any of these keys: --single
- Grouping by number of cucumber steps requires the `cuke_mode
AI-assisted analysis of grosser/parallel_tests@a06047856d (2026-08-23).
Data as JSON: /api/errors/57e709fdf72d5d91.
Report an issue: GitHub.