symfony/process · error · RuntimeException
Process is already running.
Error message
Process is already running.
What it means
A Process object represents at most one running process; calling start() while the previous instance is still running would leak the running process and corrupt the object's state, so start() throws RuntimeException if isRunning() is true.
Solutions
- Call $process->wait() (or stop()) before starting again, or check $process->isRunning().
- Create a new Process instance for each execution instead of reusing one object.
- Restructure concurrent launches into separate Process instances started in parallel.
- Guard start with if (!$process->isRunning()) { $process->start(); }.
Example fix
// before $process->start(); $process->start(); // RuntimeException // after $process->start(); $process->wait(); $process->start(); // ok, previous run finished
Defensive patterns
Strategy: validation
Validate before calling
if ($process->isRunning()) {
$process->wait(); // or stop()
}
$process->start(); Try / catch
try {
$process->start();
} catch (\RuntimeException $e) {
if ($e->getMessage() === 'Process is already running.') {
$process->wait();
$process->start();
} else {
throw $e;
}
} Prevention
- Create a fresh Process instance per execution instead of reusing one object.
- Always pair start() with wait()/stop() before any subsequent start().
- Never call start()/run() concurrently on the same instance; parallelize with separate instances.
- Wrap lifecycle transitions in a small helper that enforces wait-before-start.
When it happens
Trigger: Calling $process->start() (directly or via run()) twice without waiting for the first run to finish — e.g. calling start() again after start() without stop()/wait(), or calling run() concurrently on the same instance.
Common situations: Loops that re-start the same Process object per item; retry logic that re-calls start on a still-running process; long-running commands combined with a second start call in request handling.
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
- " " yielded a value of type " ", but only scalars and…
- A temporary file could not be opened to write the process…
- The provided cwd " " does not exist.
- Pass the callback to the "Process::start" method or call…
- Pass the callback to the "Process::start" method or call…
AI-assisted analysis of symfony/process@99b85026db (2026-09-14).
Data as JSON: /api/errors/626b57a59e6a1fed.
Report an issue: GitHub.
Appendix: source
Thrown at Process.php:321
* returns while the process runs in the background.
*
* The termination of the process can be awaited with wait().
*
* The callback receives the type of output (out or err) and some bytes from
* the output in real-time while writing the standard input to the process.
* It allows to have feedback from the independent process during execution.
*
* @param (callable('out'|'err', string):void)|null $callback A PHP callback to run whenever there is some
* output available on STDOUT or STDERR
* @param EnvArray $env
*
* @throws ProcessStartFailedException When process can't be launched
* @throws RuntimeException When process is already running
*/
public function start(?callable $callback = null, array $env = []): void
{
if ($this->isRunning()) {
throw new RuntimeException('Process is already running.');
}
$this->resetProcessData();
$this->starttime = $this->lastOutputTime = microtime(true);
$this->callback = $this->buildCallback($callback);
$descriptors = $this->getDescriptors(null !== $callback);
if ($this->env) {
$env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->env, $env, 'strcasecmp') : $this->env;
}
$env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->getDefaultEnv(), $env, 'strcasecmp') : $this->getDefaultEnv();
if (\is_array($commandline = $this->commandline)) {
$commandline = array_values(array_map(strval(...), $commandline));
} else {
$commandline = $this->replacePlaceholders($commandline, $env);
}View on GitHub (pinned to 99b85026db)