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

  1. Call start() or run() before wait()/getOutput()
  2. Use run() instead of separate start()+wait() when possible
  3. 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

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


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)