[Bug]: --shard + --parallel exits 1 when shards.json is missing/incomplete (count-based fallback)

Open
#1,731 1 comment 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
68/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
php
Domain
cli, testing

Research direction

Start with Shard.php::handleArguments and trace the count-based fallback that spawns the internal --list-tests process. Reproduce with pest tests/Feature --shard=1/2 --parallel without a usable shards.json, then verify the command completes successfully while the existing time-balanced path remains unaffected.

Written by the indexing model from the issue text.

Description

What happened?

Running --shard=N/M together with --parallel exits non-zero even though all tests pass — but only when a tests/.pest/shards.json timings file is absent or doesn't cover the sharded classes (i.e. the count-based fallback path). With a complete, fresh shards.json (time-balanced path), the same command exits 0.

Correction to the original report: I first attributed this to PHPUnit 12's failOnPhpunitWarning default flipping the exit code on a "No tests found" worker warning. After tracing it properly from a clean vendor checkout, that was wrong for this case — setting failOnPhpunitWarning="false" has no effect. The real cause is the --list-tests sub-invocation described below, which is the same root cause as #1454.

Reproduction

Same suite, ~176 feature test classes, --parallel:

Condition Exit
pest tests/Feature --shard=1/2 --parallel, no shards.json 1
pest tests/Feature --shard=1/2 --parallel, fresh shards.json 0 ✓
pest tests/Feature --parallel (no --shard) 0 ✓

When it fails, the error is:

Symfony\Component\Process\Exception\ProcessFailedException

The command "'php' './vendor/bin/pest' 'tests/Feature' '--processes=2'
'--cache-directory' '.../vendor/pestphp/pest/.temp' '--no-output' '--list-tests'" failed.

Exit Code: 2(Misuse of shell builtins)

Output:
   INFO  Unknown option "--processes". Most similar options are --covers, --colors, ...
Root cause

On the count-based fallback path (no usable shards.json), Pest's sharding enumerates the suite by spawning a child pest ... --list-tests process to build the --filter regex. Under --parallel, that child invocation is passed --processes=N, but --list-tests does not accept --processes, so it exits 2 and Pest's Process::mustRun() throws ProcessFailedException → the whole command exits non-zero.

This is the same underlying bug as #1454 (Unknown option "--processes" when sharding). This issue adds the detail that it is gated by the presence of a complete shards.json: the time-balanced path doesn't hit the broken --list-tests enumeration, so committing a current tests/.pest/shards.json is a reliable workaround — but any newly added class missing from that file silently drops you back onto the failing count-based path.

Likely fix: strip --processes / --parallel from the argv passed to the internal --list-tests sub-invocation (cf. the --parallel-stripping already done in Shard.php::handleArguments).

Versions
  • Pest: 4.7.2
  • PHPUnit: 12.5.28
  • ParaTest: 7.20.0
  • PHP: 8.5.4
Dominant language
PHP
Stars
11.7k
Forks
538
Avg merge
4d 11h
Merged PRs (30d)
8

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from pestphp/pest

All issues in pestphp/pest

Similar issues

More PHP issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.