symfony/process · error · LogicException
Cannot send signal on a non running process.
Error message
Cannot send signal on a non running process.
What it means
doSignal() needs the process PID to deliver a signal; if getPid() returns null the process is not running (never started or already terminated). With $throwException true it raises a LogicException instead of returning false.
Solutions
- Check $process->isRunning() before calling signal()
- Guard with start() first if the process was never started
- Use the non-throwing path ($throwException=false via stop(false)) when racing termination is expected
Example fix
// before
$process->signal(SIGTERM);
// after
if ($process->isRunning()) {
$process->signal(SIGTERM);
} Defensive patterns
Strategy: type-guard
Validate before calling
if ($process->isRunning()) {
$process->signal(SIGTERM);
} Type guard
function canSignal(Symfony\Component\Process\Process $p): bool { return $p->isRunning(); } Try / catch
try { $process->signal($sig); } catch (LogicException $e) { /* process not running; ignore or restart */ } Prevention
- Always gate signal() behind isRunning()
- Track process lifecycle state in your own wrapper
- Expect races: child may exit between check and signal
When it happens
Trigger: Calling $process->signal(SIGTERM) (or stop() with exceptions) on a process that was never started or has already exited.
Common situations: Signaling in a shutdown handler after the process already finished, signaling a freshly constructed Process, race where the child exited before signal() was reached.
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…
- Process must be started before calling
- Process must be terminated 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/58af61fd0b039492.
Report an issue: GitHub.
Appendix: source
Thrown at Process.php:1529
* Sends a POSIX signal to the process.
*
* @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants)
* @param bool $throwException Whether to throw exception in case signal failed
*
* @throws LogicException In case the process is not running
* @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
* @throws RuntimeException In case of failure
*/
private function doSignal(int $signal, bool $throwException): bool
{
// Signal seems to be send when sigchild is enable, this allow blocking the signal correctly in this case
if ($this->isSigchildEnabled() && \in_array($signal, $this->ignoredSignals)) {
return false;
}
if (null === $pid = $this->getPid()) {
if ($throwException) {
throw new LogicException('Cannot send signal on a non running process.');
}
return false;
}
if ('\\' === \DIRECTORY_SEPARATOR) {
exec(\sprintf('taskkill /F /T /PID %d 2>&1', $pid), $output, $exitCode);
if ($exitCode && $this->isRunning()) {
if ($throwException) {
throw new RuntimeException(\sprintf('Unable to kill the process (%s).', implode(' ', $output)));
}
return false;
}
} else {
if (!$this->isSigchildEnabled()) {
$ok = @proc_terminate($this->process, $signal);
} elseif (\function_exists('posix_kill')) {View on GitHub (pinned to 99b85026db)