composer/composer · error · RuntimeException

Failed to execute {command} {error_output}

Error message

Failed to execute {command}

{error_output}

What it means

Thrown by FossilDownloader's private execute() helper when a Fossil command (fossil pull, fossil up, etc.) returns a non-zero exit code. The code at FossilDownloader.php:116-117 checks the ProcessExecutor result and throws a RuntimeException containing the full command and its error output. This wraps any underlying Fossil CLI failure into a Composer-level exception.

Source

Thrown at src/Composer/Downloader/FossilDownloader.php:117

        foreach ($this->process->splitLines($output) as $line) {
            if (Preg::isMatch($match, $line)) {
                break;
            }
            $log .= $line;
        }

        return $log;
    }

    /**
     * @param non-empty-list<string> $command
     * @throws RuntimeException
     */
    private function execute(array $command, ?string $cwd = null, ?string &$output = null): void
    {
        if (0 !== $this->process->execute($command, $output, $cwd)) {
            throw new RuntimeException('Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput());
        }
    }

    /**
     * @inheritDoc
     */
    protected function hasMetadataRepository(string $path): bool
    {
        return is_file($path . '/.fslckout') || is_file($path . '/_FOSSIL_');
    }
}

View on GitHub (pinned to c435d285c9)

Solutions

  1. Read the embedded error_output in the exception message to see the Fossil CLI's diagnostic.
  2. Run the failing fossil command manually in the package directory to reproduce and debug.
  3. Verify network connectivity and authentication to the Fossil repository.
  4. If the checkout has local changes, stash or revert them before updating.
  5. Ensure the 'fossil' binary is installed, on PATH, and at a compatible version.

Example fix

# before
$ composer update vendor/fossil-pkg
# RuntimeException: Failed to execute fossil pull

# after: debug manually
$ cd vendor/vendor/fossil-pkg
$ fossil pull  # see actual error
$ fossil up <ref>  # then retry composer update
Defensive patterns

Strategy: try-catch

Validate before calling

// Check fossil binary availability before update
$process = new \Composer\Util\ProcessExecutor();
if (0 !== $process->execute(['fossil', 'version'], $fossilOutput)) {
    fwrite(STDERR, 'fossil binary not available: ' . $fossilOutput);
    exit(1);
}

Type guard

function fossilBinaryIsAvailable(\Composer\Util\ProcessExecutor $process): bool {
    return 0 === $process->execute(['fossil', 'version']);
}

Try / catch

try {
    $downloader->update($initial, $target, $path, $url);
} catch (\RuntimeException $e) {
    if (str_contains($e->getMessage(), 'Failed to execute fossil')) {
        // Inspect $e->getMessage() for the fossil CLI error and retry or fix
        fwrite(STDERR, $e->getMessage());
    }
    throw $e;
}

Prevention

When it happens

Trigger: The 'fossil' binary fails during doUpdate: 'fossil pull' fails due to network/auth issues, or 'fossil up' fails due to an invalid reference, merge conflict, or corrupt checkout. Any non-zero exit from the ProcessExecutor triggers it.

Common situations: The Fossil repository server is down or the URL is wrong. Network/firewall blocks the Fossil protocol. Authentication required but not configured. The checkout has uncommitted changes blocking an update. The 'fossil' binary is outdated or misconfigured.

Related errors


AI-assisted analysis of composer/composer@c435d285c9 (2026-08-07). Data as JSON: /api/errors/0a06776453686712. Report an issue: GitHub.