{"record":{"id":"7505a7cf7771e007","repo":"rectorphp/rector","slug":"parallel-main-script-was-not-found","errorCode":null,"errorMessage":"[parallel] Main script was not found","messagePattern":"\\[parallel\\] Main script was not found","errorType":"exception","errorClass":"ParallelShouldNotHappenException","httpStatus":null,"severity":"error","filePath":"src/Application/ApplicationFileProcessor.php","lineNumber":245,"sourceCode":"            $this->systemErrors[] = new SystemError($message, $file, $line);\n            return \\true;\n        };\n        set_error_handler($errorHandlerCallback);\n    }\n    private function restoreErrorHandler(): void\n    {\n        restore_error_handler();\n    }\n    /**\n     * @param string[] $filePaths\n     * @param callable(int $stepCount): void $postFileCallback\n     */\n    private function runParallel(array $filePaths, InputInterface $input, callable $postFileCallback): ProcessResult\n    {\n        $schedule = $this->scheduleFactory->create($this->cpuCoreCountProvider->provide(), SimpleParameterProvider::provideIntParameter(Option::PARALLEL_JOB_SIZE), SimpleParameterProvider::provideIntParameter(Option::PARALLEL_MAX_NUMBER_OF_PROCESSES), $filePaths);\n        $mainScript = $this->resolveCalledRectorBinary();\n        if ($mainScript === null) {\n            throw new ParallelShouldNotHappenException('[parallel] Main script was not found');\n        }\n        // mimics see https://github.com/phpstan/phpstan-src/commit/9124c66dcc55a222e21b1717ba5f60771f7dda92#diff-387b8f04e0db7a06678eb52ce0c0d0aff73e0d7d8fc5df834d0a5fbec198e5daR139\n        return $this->parallelFileProcessor->process($schedule, $mainScript, $postFileCallback, $input);\n    }\n    /**\n     * Path to called \"rector\" binary file, e.g. \"vendor/bin/rector\" returns \"vendor/bin/rector\" This is needed to re-call the\n     * rector binary in sub-process in the same location.\n     */\n    private function resolveCalledRectorBinary(): ?string\n    {\n        if (!isset($_SERVER[self::ARGV][0])) {\n            return null;\n        }\n        $potentialRectorBinaryPath = $_SERVER[self::ARGV][0];\n        if (!file_exists($potentialRectorBinaryPath)) {\n            return null;\n        }\n        return $potentialRectorBinaryPath;","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/rectorphp/rector/blob/408fcb0ff1833e3d26cbc9b04c23a77565814a16/src/Application/ApplicationFileProcessor.php#L227-L263","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before: custom runner that lost argv[0]\n$_SERVER['argv'] = ['rector'];\n$application->run();\n\n// after: point argv[0] at the real binary file\n$_SERVER['argv'][0] = __DIR__ . '/vendor/bin/rector';\n$application->run();","handlingStrategy":"validation","validationCode":"// before invoking rector programmatically, ensure argv[0] is a real binary file\n$rectorBinary = __DIR__ . '/vendor/bin/rector';\nif (!is_file($rectorBinary)) {\n    throw new RuntimeException('rector binary missing at ' . $rectorBinary);\n}\n$_SERVER['argv'][0] = $rectorBinary; // child processes re-call this path","typeGuard":null,"tryCatchPattern":"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.","preventionTips":["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"],"tags":["php","rector","parallel","subprocess","cli","argv"],"backgroundTag":"subprocess-main-script-not-found","analyzedSha":"408fcb0ff1833e3d26cbc9b04c23a77565814a16","analyzedAt":"2026-08-21T05:11:02.643Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}