Skip to content

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

Description

@atymic

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions