symfony/process · error · LogicException

Output has been disabled.

Error message

Output has been disabled.

What it means

When a Process is created with disableOutput() (or null callback + disabled output), all output-reading APIs are forbidden. readPipesForOutput() checks outputDisabled first and throws a LogicException because there is no pipe data to read by design.

Solutions

  1. Remove disableOutput() if output is needed (must be before start)
  2. Check $process->isOutputDisabled() before reading
  3. If output is genuinely unneeded, drop the getOutput()/getIterator() calls

Example fix

// before
$process->disableOutput();
$process->start();
echo $process->getOutput();
// after
$process->start();
echo $process->getOutput();
Defensive patterns

Strategy: validation

Validate before calling

if ($process->isOutputDisabled()) {
    throw new LogicException('Output is disabled; cannot read output.');
}

Try / catch

try { $out = $process->getOutput(); } catch (LogicException $e) { $out = null; }

Prevention

When it happens

Trigger: Calling getOutput(), getErrorOutput(), getIncrementalOutput(), getIncrementalErrorOutput() or iterating getIterator() after $process->disableOutput() (or after passing disableOutput via constructor options).

Common situations: Disabling output for performance in background jobs but later needing stdout for debugging; copy-pasted code reading output of a fire-and-forget process.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of symfony/process@99b85026db (2026-09-14). Data as JSON: /api/errors/1b92a481cc42f3b7. Report an issue: GitHub.

Appendix: source

Thrown at Process.php:1412

        ob_start();
        phpinfo(\INFO_GENERAL);

        return self::$sigchild = str_contains(ob_get_clean(), '--enable-sigchild');
    }

    /**
     * Reads pipes for the freshest output.
     *
     * @param string $caller   The name of the method that needs fresh outputs
     * @param bool   $blocking Whether to use blocking calls or not
     *
     * @throws LogicException in case output has been disabled or process is not started
     */
    private function readPipesForOutput(string $caller, bool $blocking = false): void
    {
        if ($this->outputDisabled) {
            throw new LogicException('Output has been disabled.');
        }

        $this->requireProcessIsStarted($caller);

        $this->updateStatus($blocking);
    }

    /**
     * Validates and returns the filtered timeout.
     *
     * @throws InvalidArgumentException if the given timeout is a negative number
     */
    private function validateTimeout(?float $timeout): ?float
    {
        $timeout = (float) $timeout;

        if (0.0 === $timeout) {
            $timeout = null;

View on GitHub (pinned to 99b85026db)