symfony/process · error · LogicException
Process must be started before calling
Error message
Process must be started before calling "%s()".
What it means
requireProcessIsStarted() guards APIs that need a live or at least started process. Calling wait(), waitUntil() or any output reader before start()/run() throws a LogicException naming the called function.
Solutions
- Call start() or run() before wait()/getOutput()
- Use run() instead of separate start()+wait() when possible
- Add an isStarted() guard before calling these methods
Example fix
// before $process = new Process(['ls']); $process->wait(); // after $process = new Process(['ls']); $process->run(); // or $process->start(); ... $process->wait();
Defensive patterns
Strategy: validation
Validate before calling
if (!$process->isStarted()) {
$process->start();
}
$process->wait(); Try / catch
try { $process->wait(); } catch (LogicException $e) { $process->run(); } Prevention
- Prefer run() over manual start()+wait() for simple cases
- Wrap process execution in a helper that enforces lifecycle order
- Never call wait()/getOutput() on a freshly constructed Process
When it happens
Trigger: Calling $process->wait() or $process->getOutput() before $process->start(); calling wait() after constructing a Process without running it.
Common situations: Misordered code where start() is conditional but wait() is not, reading output before run(), tests forgetting to start the process.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Setting ignored signals while the process is running is not…
- Cannot send signal on a non running process.
- Process must be terminated before calling
- Start time is only available after process start.
- Invalid option " " passed to " ()". Supported options are "…
AI-assisted analysis of symfony/process@99b85026db (2026-09-14).
Data as JSON: /api/errors/b2e5cb2bf181f295.
Report an issue: GitHub.
Appendix: source
Thrown at Process.php:1658
}
$cmd = $comSpec.' /V:ON /E:ON /D /C ('.str_replace("\n", ' ', $cmd).')';
foreach ($this->processPipes->getFiles() as $offset => $filename) {
$cmd .= ' '.$offset.'>"'.$filename.'"';
}
return $cmd;
}
/**
* Ensures the process is running or terminated, throws a LogicException if the process has a not started.
*
* @throws LogicException if the process has not run
*/
private function requireProcessIsStarted(string $functionName): void
{
if (!$this->isStarted()) {
throw new LogicException(\sprintf('Process must be started before calling "%s()".', $functionName));
}
}
/**
* Ensures the process is terminated, throws a LogicException if the process has a status different than "terminated".
*
* @throws LogicException if the process is not yet terminated
*/
private function requireProcessIsTerminated(string $functionName): void
{
if (!$this->isTerminated()) {
throw new LogicException(\sprintf('Process must be terminated before calling "%s()".', $functionName));
}
}
/**
* Escapes a string to be used as a shell argument.
*/View on GitHub (pinned to 99b85026db)