rectorphp/rector · error · InvalidConfigurationException

Provided dumped Symfony container must have "xml" suffix. "%

Error message

Provided dumped Symfony container must have "xml" suffix. "%s" given

What it means

withSymfonyContainerXml() lets Symfony-aware rules read your real service definitions from a dumped XML container (var/cache/dev/App_KernelDevDebugContainer.xml). The builder validates the path ends with .xml and throws InvalidConfigurationException otherwise, catching cases where the PHP container file or an unrelated file is passed. Supply the XML dump produced by cache:warmup/debug mode.

Source

Thrown at src/Configuration/RectorConfigBuilder.php:644

     * @param string[] $phpstanConfigs
     */
    public function withPHPStanConfigs(array $phpstanConfigs): self
    {
        $this->phpstanConfigs = $phpstanConfigs;
        return $this;
    }
    /**
     * @param PhpVersion::* $phpVersion
     */
    public function withPhpVersion(int $phpVersion): self
    {
        $this->phpVersion = $phpVersion;
        return $this;
    }
    public function withSymfonyContainerXml(string $symfonyContainerXmlFile): self
    {
        if (substr_compare($symfonyContainerXmlFile, '.xml', -strlen('.xml')) !== 0) {
            throw new InvalidConfigurationException(sprintf('Provided dumped Symfony container must have "xml" suffix. "%s" given', $symfonyContainerXmlFile));
        }
        $this->symfonyContainerXmlFile = $symfonyContainerXmlFile;
        return $this;
    }
    public function withSymfonyContainerPhp(string $symfonyContainerPhpFile): self
    {
        if (substr_compare($symfonyContainerPhpFile, '.php', -strlen('.php')) !== 0) {
            throw new InvalidConfigurationException(sprintf('Provided dumped Symfony container must have "php" suffix. "%s" given', $symfonyContainerPhpFile));
        }
        $this->symfonyContainerPhpFile = $symfonyContainerPhpFile;
        return $this;
    }
    /**
     * Raise your type coverage from the safest type rules
     * to more affecting ones, one level at a time
     */
    public function withTypeCoverageLevel(int $level): self
    {

View on GitHub (pinned to 408fcb0ff1)

Solutions

  1. Warm the cache and pass the XML dump: bin/console cache:warmup --env=dev, then use var/cache/dev/App_KernelDevDebugContainer.xml
  2. Locate it robustly with glob: glob(__DIR__ . '/var/cache/dev/*Container.xml')[0]
  3. If your setup only produces a PHP container, use ->withSymfonyContainerPhp() with that file instead

Example fix

// before
->withSymfonyContainerXml(__DIR__ . '/var/cache/dev/App_KernelDevDebugContainer.php')

// after
->withSymfonyContainerXml(glob(__DIR__ . '/var/cache/dev/*Container.xml')[0])
Defensive patterns

Strategy: validation

Validate before calling

// resolve the dumped XML container before configuring
$containerXml = glob(__DIR__ . '/var/cache/dev/*Container.xml')[0] ?? null;
if ($containerXml === null) {
    exit('Run `bin/console cache:warmup` first; no *Container.xml found');
}
return RectorConfig::configure()->withSymfonyContainerXml($containerXml);

Type guard

function isSymfonyXmlContainerDump(string $path): bool
{
    return substr($path, -4) === '.xml' && is_file($path);
}

Try / catch

catch \Rector\Exception\Configuration\InvalidConfigurationException; if the message complains about the xml suffix, re-resolve the dump path with glob(...*Container.xml) and re-run.

Prevention

When it happens

Trigger: Calling ->withSymfonyContainerXml(__DIR__ . '/var/cache/dev/App_KernelDevDebugContainer.php') (wrong -- PHP dump), or passing the kernel/class_.php service file, or any non-xml path.

Common situations: First-time setup of symfony rules copying a stale path from docs; container dump naming differs after config changes (the hash suffix changes), so devs guess and pick the .php sibling file.

Related errors


AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21). Data as JSON: /api/errors/3f4e4f0b5640238c. Report an issue: GitHub.