symfony/process · error · LogicException
Process must be terminated before calling
Error message
Process must be terminated before calling "%s()".
What it means
requireProcessIsTerminated() guards post-mortem accessors (hasBeenSignaled, getTermSignal, hasBeenStopped, getStopSignal). These reflect final exit data that only exists after the process terminated; calling them earlier throws a LogicException.
Solutions
- Call wait() and ensure the process finished before reading signal info
- Check isTerminated() before calling these accessors
- Use callbacks (e.g. wait's callable) that run only at termination for final reporting
Example fix
// before
$process->start();
$sig = $process->getTermSignal();
// after
$process->run();
if ($process->isTerminated()) {
$sig = $process->hasBeenSignaled() ? $process->getTermSignal() : null;
} Defensive patterns
Strategy: validation
Validate before calling
if ($process->isTerminated()) {
$signaled = $process->hasBeenSignaled();
$termSignal = $signaled ? $process->getTermSignal() : null;
} Type guard
function exitSignal(Symfony\Component\Process\Process $p): ?int { return $p->isTerminated() && $p->hasBeenSignaled() ? $p->getTermSignal() : null; } Try / catch
try { $sig = $process->getTermSignal(); } catch (LogicException $e) { $sig = null; } Prevention
- Only read exit/signal data after wait() or run() returns
- Use isTerminated() as a gate for all post-mortem accessors
- Collect final status in the wait() callback which runs after termination
When it happens
Trigger: Calling $process->getTermSignal() or hasBeenSignaled() while the process is still running, e.g. inside progress polling before wait() returned.
Common situations: Checking exit signal information in a loop before completion, calling signal accessors right after start(), integrating with callbacks that run before termination.
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 started before calling
- Invalid option " " passed to " ()". Supported options are "…
- Output has been disabled.
AI-assisted analysis of symfony/process@99b85026db (2026-09-14).
Data as JSON: /api/errors/8d042b8115fc6eb9.
Report an issue: GitHub.
Appendix: source
Thrown at Process.php:1670
*
* @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.
*/
private function escapeArgument(?string $argument): string
{
if ('' === $argument || null === $argument) {
return '""';
}
if ('\\' !== \DIRECTORY_SEPARATOR) {
return "'".str_replace("'", "'\\''", $argument)."'";
}
if (str_contains($argument, "\0")) {
$argument = str_replace("\0", '?', $argument);
}
if (!preg_match('/[()%!^"<>&|\s[\]=;*?\'$]/', $argument)) {View on GitHub (pinned to 99b85026db)