rectorphp/rector · error · ParallelShouldNotHappenException
[parallel] Main script was not found
Error message
[parallel] Main script was not found
What it means
Rector runs files in parallel by re-invoking its own binary as child processes, so it must know which script started the run. resolveCalledRectorBinary() reads $_SERVER['argv'][0] and requires that value to be an existing file on disk; if argv[0] is unset or the file no longer exists, runParallel() aborts with ParallelShouldNotHappenException. This is an environment/invocation problem, not a problem with your code or config.
Source
Thrown at src/Application/ApplicationFileProcessor.php:245
$this->systemErrors[] = new SystemError($message, $file, $line);
return \true;
};
set_error_handler($errorHandlerCallback);
}
private function restoreErrorHandler(): void
{
restore_error_handler();
}
/**
* @param string[] $filePaths
* @param callable(int $stepCount): void $postFileCallback
*/
private function runParallel(array $filePaths, InputInterface $input, callable $postFileCallback): ProcessResult
{
$schedule = $this->scheduleFactory->create($this->cpuCoreCountProvider->provide(), SimpleParameterProvider::provideIntParameter(Option::PARALLEL_JOB_SIZE), SimpleParameterProvider::provideIntParameter(Option::PARALLEL_MAX_NUMBER_OF_PROCESSES), $filePaths);
$mainScript = $this->resolveCalledRectorBinary();
if ($mainScript === null) {
throw new ParallelShouldNotHappenException('[parallel] Main script was not found');
}
// mimics see https://github.com/phpstan/phpstan-src/commit/9124c66dcc55a222e21b1717ba5f60771f7dda92#diff-387b8f04e0db7a06678eb52ce0c0d0aff73e0d7d8fc5df834d0a5fbec198e5daR139
return $this->parallelFileProcessor->process($schedule, $mainScript, $postFileCallback, $input);
}
/**
* Path to called "rector" binary file, e.g. "vendor/bin/rector" returns "vendor/bin/rector" This is needed to re-call the
* rector binary in sub-process in the same location.
*/
private function resolveCalledRectorBinary(): ?string
{
if (!isset($_SERVER[self::ARGV][0])) {
return null;
}
$potentialRectorBinaryPath = $_SERVER[self::ARGV][0];
if (!file_exists($potentialRectorBinaryPath)) {
return null;
}
return $potentialRectorBinaryPath;View on GitHub (pinned to 408fcb0ff1)
Solutions
- Run Rector directly through its CLI entry point: vendor/bin/rector process src (or rector.phar process src)
- If you wrap Rector, make sure $_SERVER['argv'][0] is set to the real, existing binary path before booting the console application
- Reinstall the binary so the file argv[0] points at exists: composer reinstall rector/rector or composer global update
- Avoid launching rector from php -r or an in-process include; shell out to the binary instead
Example fix
// before: custom runner that lost argv[0] $_SERVER['argv'] = ['rector']; $application->run(); // after: point argv[0] at the real binary file $_SERVER['argv'][0] = __DIR__ . '/vendor/bin/rector'; $application->run();
Defensive patterns
Strategy: validation
Validate before calling
// before invoking rector programmatically, ensure argv[0] is a real binary file
$rectorBinary = __DIR__ . '/vendor/bin/rector';
if (!is_file($rectorBinary)) {
throw new RuntimeException('rector binary missing at ' . $rectorBinary);
}
$_SERVER['argv'][0] = $rectorBinary; // child processes re-call this path Try / catch
catch \Symplify\EasyParallel\Exception\ParallelShouldNotHappenException around the run and surface a hint: 'run rector directly via vendor/bin/rector so parallel workers can re-spawn the binary'. Do not retry blindly; fix the invocation.
Prevention
- Invoke rector only through its shipped CLI entry point (vendor/bin/rector or rector.phar)
- Never delete or overwrite the rector binary mid-run (delay composer update until after the run)
- When wrapping rector in a custom runner, set $_SERVER['argv'][0] to the existing binary path before boot
When it happens
Trigger: Running Rector with more files than fit one job when argv[0] is not a path to an existing file: invoking Rector programmatically from another PHP process, via php -r, through a custom wrapper/harness, or when the binary/symlink that started the process is deleted or moved mid-run (e.g. global symlink to an uninstalled vendor).
Common situations: CI pipelines that call rector through a bespoke runner script, global installations whose symlink target was removed by a composer update, or embedding rector in another tool that shims argv.
Related errors
- Short rule name "%s" is ambiguous. Specify the full rule nam
- Rule "%s" exists, but is not registered in your Rector confi
- Rule "%s" was not found.%sThe rule has no namespace. Make su
- Rule "%s" was not found.%sMake sure it is registered in your
- Rector name cannot be empty
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/7505a7cf7771e007.
Report an issue: GitHub.